# -*- coding: utf-8 -*- 
#
# Description:
#
#  Definiton
#
#
#
# Changes:
#
# 2012-01-10
# Initial Commit
#
#
# Copyright 2010-2012, WyDev Team.
# Author: Polo35 (polo35580@hotmail.fr)
#
# Licenced under Academic Free License version 3.0
# Review WyGui README & LICENSE files for further details.

nname: 0
n 0(None)[self.name = name
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16af6c>}
nname: 0
n 0(None)[return self.name
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16af6c>}
nname: 0
n 0(None)[return self.name
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16ae2c>}
nname: 0
n 0(None)[return cmp(self.name, other.name)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e1ec>}
nname: 0
n 0(None)[return self.name == other.name
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e08c>}
nname: 69
n 69(None)[return None
]:
	i: 61(), 68()
	o: 

nname: 68
n 68(None)[]:
	i: 0(t)
	o: 69()

nname: 61
n 61(None)[Task(self._post, arg).start(0, timeout=None)
]:
	i: 46(), 57()
	o: 69()

nname: 57
n 57(None)[]:
	i: 9(f)
	o: 61()

nname: 46
n 46(None)[]:
	i: 9(t)
	o: 61()

nname: 9
n 9(arg is not None)[]:
	i: 0(f)
	o: 46(t), 57(f)

nname: 0
n 0(Event.drop_all)[]:
	i: 
	o: 9(f), 68(t)

nname: 69
n 69(None)[return None
]:
	i: 9(), 0(t)
	o: 

nname: 9
n 9(None)[if arg is not None:
	pass
Task(self._post, arg).start(0, timeout=None)
]:
	i: 0(f)
	o: 69()

nname: 0
n 0(Event.drop_all)[]:
	i: 
	o: 9(f), 69(t)

nname: 0
n 0(None)[if not Event.drop_all:
	if arg is not None:
		pass
	Task(self._post, arg).start(0, timeout=None)
return None
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e4ac>}
nname: 39
n 39(None)[]:
	i: 0(AL), 38()
	o: 

nname: 38
n 38(None)[]:
	i: 12(AF), 22()
	o: 39()

nname: 22
n 22(None)[for watcher in self.watchers:
watcher(self)
]:
	i: 12(for)
	o: 38()

nname: 12
n 12(None)[]:
	i: 0(loop)
	o: 22(for), 38(AF)

nname: 0
n 0(None)[self.arg = arg
]:
	i: 
	o: 12(loop), 39(AL)

nname: 39
n 39(None)[]:
	i: 22()
	o: 

nname: 22
n 22(None)[for watcher in self.watchers:
	watcher(self)
]:
	i: 0(for)
	o: 39()

nname: 0
n 0(None)[self.arg = arg
]:
	i: 
	o: 22(for)

nname: 39
n 39(None)[]:
	i: 0()
	o: 

nname: 0
n 0(None)[self.arg = arg
for watcher in self.watchers:
	watcher(self)
]:
	i: 
	o: 39()

nname: 0
n 0(None)[self.arg = arg
for watcher in self.watchers:
	watcher(self)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e4ac>}
nname: 6
n 6(None)[__doc__ = ' Named events,\n    one can subscribe events and be notified when they are post()ed '
__slots__ = ['name', 'arg']
watchers = []
drop_all = False
def __init__(self, name):
	self.name = name

def __str__(self):
	return self.name

def __hash__(self):
	return self.name

def __cmp__(self, other):
	return cmp(self.name, other.name)

def __eq__(self, other):
	return self.name == other.name

def post(self, arg=None):
	if not Event.drop_all:
		if arg is not None:
			pass
		Task(self._post, arg).start(0, timeout=None)
	return None

def _post(self, arg=None):
	self.arg = arg
	for watcher in self.watchers:
		watcher(self)

]:
	i: 
	o: 

self.nodes: {6: <unpyclib.structure.node instance at 0xa16abcc>}
nname: 0
n 0(None)[self.name = name
self.repeat = repeat
self._loop_task = Task(self._repeat)
self._stop_task = Task(self._loop_task.stop)
self._count = 0
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e6cc>}
nname: 0
n 0(None)[return self.name
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e3ac>}
nname: 0
n 0(None)[return self.name
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e2ec>}
nname: 0
n 0(None)[return cmp(self.name, other.name)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e72c>}
nname: 0
n 0(None)[return self.name == other.name
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e86c>}
nname: 127
n 127(None)[]:
	i: 37(JA), 103(), 126()
	o: 

nname: 126
n 126(None)[]:
	i: 0(t)
	o: 127()

nname: 103
n 103(None)[self._stop_task.start(self.timeout)
]:
	i: 9(t)
	o: 127()

nname: 37
n 37(None)[self._count = 0
self._loop_task.start(delay=self.repeat, init_delay=0.01, loop=True)
self._stop_task.start(self.timeout)
]:
	i: 9(f)
	o: 127(JA)

nname: 9
n 9(self._loop_task.running)[self._loop_task.args = [arg]
]:
	i: 0(f)
	o: 37(f), 103(t)

nname: 0
n 0(Event.drop_all)[]:
	i: 
	o: 9(f), 126(t)

nname: 0
n 0(None)[if not Event.drop_all:
	self._loop_task.args = [arg]
	if not self._loop_task.running:
		self._count = 0
		self._loop_task.start(delay=self.repeat, init_delay=0.01, loop=True)
		self._stop_task.start(self.timeout)
	else:
		self._stop_task.start(self.timeout)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16ed6c>}
nname: 151
n 151(None)[return None
]:
	i: 103(), 129(), 150(AE)
	o: 

nname: 129
n 129(None)[self._loop_task.ival = self.repeat
]:
	i: 66(except)
	o: 151()

nname: 103
n 103(None)[self._loop_task.ival = self.accels[self._count]
]:
	i: 66(try)
	o: 151()

nname: 66
n 66(None)[timeout = None
Task(self._post, arg).start(0, timeout=timeout)
]:
	i: 44(), 62()
	o: 103(try), 129(except)

nname: 62
n 62(None)[]:
	i: 0&27(f)
	o: 66()

nname: 44
n 44(None)[]:
	i: 0&27(t)
	o: 66()

nname: 0&27
n 0&27('timeout' in arg and arg['timeout'] is not None)[self._count += 1
]:
	i: 
	o: 44(t), 62(f)

nname: 129
n 129(None)[except:
	self._loop_task.ival = self.repeat
return None
]:
	i: 0&27()
	o: 

nname: 0&27
n 0&27(None)[self._count += 1
if 'timeout' in arg and arg['timeout'] is not None:
	pass
timeout = None
Task(self._post, arg).start(0, timeout=timeout)
try:
	self._loop_task.ival = self.accels[self._count]
]:
	i: 
	o: 129()

nname: 0&27
n 0&27(None)[self._count += 1
if 'timeout' in arg and arg['timeout'] is not None:
	pass
timeout = None
Task(self._post, arg).start(0, timeout=timeout)
try:
	self._loop_task.ival = self.accels[self._count]
except:
	self._loop_task.ival = self.repeat
return None
]:
	i: 
	o: 

self.nodes: {'0&27': <unpyclib.structure.node instance at 0xa16b58c>}
nname: 55
n 55(None)[]:
	i: 0(AL), 54()
	o: 

nname: 54
n 54(None)[]:
	i: 28(AF), 38()
	o: 55()

nname: 38
n 38(None)[for watcher in self.watchers:
watcher(self)
]:
	i: 28(for)
	o: 54()

nname: 28
n 28(None)[]:
	i: 0(loop)
	o: 38(for), 54(AF)

nname: 0
n 0(None)[self.arg = arg
self.arg['count'] = self._count
]:
	i: 
	o: 28(loop), 55(AL)

nname: 55
n 55(None)[]:
	i: 38()
	o: 

nname: 38
n 38(None)[for watcher in self.watchers:
	watcher(self)
]:
	i: 0(for)
	o: 55()

nname: 0
n 0(None)[self.arg = arg
self.arg['count'] = self._count
]:
	i: 
	o: 38(for)

nname: 55
n 55(None)[]:
	i: 0()
	o: 

nname: 0
n 0(None)[self.arg = arg
self.arg['count'] = self._count
for watcher in self.watchers:
	watcher(self)
]:
	i: 
	o: 55()

nname: 0
n 0(None)[self.arg = arg
self.arg['count'] = self._count
for watcher in self.watchers:
	watcher(self)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16edec>}
nname: 6
n 6(None)[__doc__ = ' Like Event but handle repeat internally '
__slots__ = ['name', 'arg', '_stop_task', '_loop_task', '_count', 'repeat', 'timeout', 'accels']
watchers = []
drop_all = False
def __init__(self, name, repeat=0.10000000000000001, timeout=0.13, accels=None):
	self.name = name
	self.repeat = repeat
	self._loop_task = Task(self._repeat)
	self._stop_task = Task(self._loop_task.stop)
	self._count = 0

def __str__(self):
	return self.name

def __hash__(self):
	return self.name

def __cmp__(self, other):
	return cmp(self.name, other.name)

def __eq__(self, other):
	return self.name == other.name

def post(self, arg=None):
	if not Event.drop_all:
		self._loop_task.args = [arg]
		if not self._loop_task.running:
			self._count = 0
			self._loop_task.start(delay=self.repeat, init_delay=0.01, loop=True)
			self._stop_task.start(self.timeout)
		else:
			self._stop_task.start(self.timeout)

def _repeat(self, arg):
	self._count += 1
	if 'timeout' in arg and arg['timeout'] is not None:
		pass
	timeout = None
	Task(self._post, arg).start(0, timeout=timeout)
	try:
		self._loop_task.ival = self.accels[self._count]
	except:
		self._loop_task.ival = self.repeat
	return None

def _post(self, arg=None):
	self.arg = arg
	self.arg['count'] = self._count
	for watcher in self.watchers:
		watcher(self)

]:
	i: 
	o: 

self.nodes: {6: <unpyclib.structure.node instance at 0xa16ab0c>}
nname: 0
n 0(None)[Event.drop_all = bool
CleverEvent.drop_all = bool
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa156c4c>}
nname: 0
n 0(None)[Event.watchers.append(callback)
CleverEvent.watchers.append(callback)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa156b8c>}
nname: 0
n 0(None)[sched._rfds[fd].append(callback)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa1568ac>}
nname: 0
n 0(None)[sched._idle_infos['on_enter'] = callback
sched._idle_infos['on_exit'] = exit_callback
sched._idle_infos['threshold'] = idle_threshold
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16a5ac>}
nname: 0
n 0(None)[self.task = Task(None)
self.task.delay = delay
return None
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16a6cc>}
nname: 0
n 0(None)[log.debug('Starting Task for %s', self.task.fn)
self.task.args, self.task.kw = args, kw
self.task.start()
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e38c>}
nname: 0
n 0(None)[self.task.fn = fn
def decorated(*args, **args):
	log.debug('Starting Task for %s', self.task.fn)
	self.task.args, self.task.kw = args, kw
	self.task.start()

decorated.task = self.task
return decorated
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16a8ac>}
nname: 6
n 6(None)[__doc__ = "Decorator that makes the target callable run in a Task.\n\n    Useful for e.g. dbus callbacks that are called in a separate thread.\n\n    If you're stacking decorators with side effects, @tasked should be\n    the outermost decorator. Otherwise the code from the outer decorators\n    will be called before the actual function code, and there will *not*\n    be much rejoicing.\n\n    Usage:\n        >>> @tasked(0.1)\n        >>> def foo(*args, **kw):\n        ...     pass\n        >>> # Run foo in a Task with a 0.1s delay\n        >>> foo(bar, baz, fnord=None)\n\n    /!\\ WARNING /!\\ Do *not* use on instance methods that are likely\n    to be called at the same time with different arguments in different threads.\n    Interference between the calls may occur if that happens\n    (e.g. all calls but one being ignored).\n    Yes, that'll be painful to debug, so don't do that, okay?\n    "
def __init__(self, delay):
	self.task = Task(None)
	self.task.delay = delay
	return None

def __call__(self, fn):
	self.task.fn = fn
	def decorated(*args, **args):
		log.debug('Starting Task for %s', self.task.fn)
		self.task.args, self.task.kw = args, kw
		self.task.start()

	decorated.task = self.task
	return decorated

]:
	i: 
	o: 

self.nodes: {6: <unpyclib.structure.node instance at 0xa16a46c>}
nname: 0
n 0(None)[self.args = args
self.kw = kw
self.fn = fn
self.ival = None
self.running = False
self.timeout = None
self._generator = None
self._considered_idle = False
return None
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e9ec>}
nname: 76
n 76(None)[return '<%s %s task %s calling %s>' % ('stopped', 'busy', 'every %ss' % self.ival, self.fn)
]:
	i: 58(), 65()
	o: 

nname: 65
n 65(None)[]:
	i: 43(f)
	o: 76()

nname: 58
n 58(None)[]:
	i: 43(t)
	o: 76()

nname: 43
n 43(self.ival is None)[]:
	i: 32(), 39()
	o: 58(t), 65(f)

nname: 39
n 39(None)[]:
	i: 23(f)
	o: 43()

nname: 32
n 32(None)[]:
	i: 23(t)
	o: 43()

nname: 23
n 23(self._considered_idle)[]:
	i: 12(), 19()
	o: 32(t), 39(f)

nname: 19
n 19(None)[]:
	i: 0(f)
	o: 23()

nname: 12
n 12(None)[]:
	i: 0(t)
	o: 23()

nname: 0
n 0(self.running)[]:
	i: 
	o: 12(t), 19(f)

nname: 43
n 43(None)[if self.ival is None:
	pass
return '<%s %s task %s calling %s>' % ('stopped', 'busy', 'every %ss' % self.ival, self.fn)
]:
	i: 0()
	o: 

nname: 0
n 0(None)[if self.running:
	pass
if self._considered_idle:
	pass
]:
	i: 
	o: 43()

nname: 0
n 0(None)[if self.running:
	pass
if self._considered_idle:
	pass
if self.ival is None:
	pass
return '<%s %s task %s calling %s>' % ('stopped', 'busy', 'every %ss' % self.ival, self.fn)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e6cc>}
nname: 285
n 285(None)[sched.add(self, delay, self._generator)
return self
]:
	i: 274(), 281()
	o: 

nname: 281
n 281(None)[]:
	i: 232(f)
	o: 285()

nname: 274
n 274(None)[]:
	i: 232(t)
	o: 285()

nname: 232
n 232(init_delay is not None)[self.ival = None
self._generator = self._generate()
]:
	i: 221(), 228()
	o: 274(t), 281(f)

nname: 228
n 228(None)[]:
	i: 215(f)
	o: 232()

nname: 221
n 221(None)[]:
	i: 215(t)
	o: 232()

nname: 215
n 215(loop)[]:
	i: 201(), 214()
	o: 221(t), 228(f)

nname: 214
n 214(None)[]:
	i: 189(f)
	o: 215()

nname: 201
n 201(None)[self.timeout = timeout
]:
	i: 189(t)
	o: 215()

nname: 189
n 189(timeout is not None)[]:
	i: 179(), 188()
	o: 201(t), 214(f)

nname: 188
n 188(None)[]:
	i: 143(f)
	o: 189()

nname: 179
n 179(None)[self.delay = 1.0
]:
	i: 168(), 175()
	o: 189()

nname: 175
n 175(None)[]:
	i: 155(f)
	o: 179()

nname: 168
n 168(None)[]:
	i: 155(t)
	o: 179()

nname: 155
n 155(delay is not None)[]:
	i: 143(t)
	o: 168(t), 175(f)

nname: 143
n 143(delay is not None)[]:
	i: 136(), 142()
	o: 155(t), 188(f)

nname: 142
n 142(None)[]:
	i: 97(f)
	o: 143()

nname: 136
n 136(None)[loop = True
]:
	i: 125(), 132()
	o: 143()

nname: 132
n 132(None)[]:
	i: 109(f)
	o: 136()

nname: 125
n 125(None)[]:
	i: 109(t)
	o: 136()

nname: 109
n 109(self.ival is None)[]:
	i: 97(t)
	o: 125(t), 132(f)

nname: 97
n 97(loop is None)[]:
	i: 83(), 96()
	o: 109(t), 142(f)

nname: 96
n 96(None)[]:
	i: 71(f)
	o: 97()

nname: 83
n 83(None)[delay = self.delay
]:
	i: 71(t)
	o: 97()

nname: 71
n 71(delay is None)[]:
	i: 57(), 70()
	o: 83(t), 96(f)

nname: 70
n 70(None)[]:
	i: 24(f)
	o: 71()

nname: 57
n 57(None)[self._considered_idle = consider_idle
]:
	i: 24(t)
	o: 71()

nname: 24
n 24(consider_idle is not None)[self.running = sched.ts
self._paused = None
]:
	i: 9(), 23()
	o: 57(t), 70(f)

nname: 23
n 23(None)[]:
	i: 0(f)
	o: 24()

nname: 9
n 9(None)[self.stop()
]:
	i: 0(t)
	o: 24()

nname: 0
n 0(self.running)[]:
	i: 
	o: 9(t), 23(f)

nname: 232
n 232(None)[self.ival = None
self._generator = self._generate()
if init_delay is not None:
	pass
sched.add(self, delay, self._generator)
return self
]:
	i: 189()
	o: 

nname: 189
n 189(None)[if timeout is not None:
	self.timeout = timeout
if loop:
	pass
]:
	i: 155(), 143(f)
	o: 232()

nname: 155
n 155(None)[if delay is not None:
	pass
self.delay = 1.0
]:
	i: 143(t)
	o: 189()

nname: 143
n 143(delay is not None)[]:
	i: 109(), 71(f)
	o: 155(t), 189(f)

nname: 109
n 109(None)[if self.ival is None:
	pass
loop = True
]:
	i: 71(t)
	o: 143()

nname: 71
n 71(loop is None)[if delay is None:
	delay = self.delay
]:
	i: 0()
	o: 109(t), 143(f)

nname: 0
n 0(None)[if self.running:
	self.stop()
self.running = sched.ts
self._paused = None
if consider_idle is not None:
	self._considered_idle = consider_idle
]:
	i: 
	o: 71()

nname: 232
n 232(None)[self.ival = None
self._generator = self._generate()
if init_delay is not None:
	pass
sched.add(self, delay, self._generator)
return self
]:
	i: 143()
	o: 

nname: 143
n 143(None)[if delay is not None:
	if delay is not None:
		pass
	self.delay = 1.0
if timeout is not None:
	self.timeout = timeout
if loop:
	pass
]:
	i: 0(f)
	o: 232()

nname: 0
n 0(None)[if self.running:
	self.stop()
self.running = sched.ts
self._paused = None
if consider_idle is not None:
	self._considered_idle = consider_idle
if delay is None:
	delay = self.delay
if loop is None:
	if self.ival is None:
		pass
	loop = True
]:
	i: 
	o: 143()

nname: 232
n 232(None)[self.ival = None
self._generator = self._generate()
if init_delay is not None:
	pass
sched.add(self, delay, self._generator)
return self
]:
	i: 0()
	o: 

nname: 0
n 0(None)[if self.running:
	self.stop()
self.running = sched.ts
self._paused = None
if consider_idle is not None:
	self._considered_idle = consider_idle
if delay is None:
	delay = self.delay
if loop is None:
	if self.ival is None:
		pass
	loop = True
if delay is not None:
	if delay is not None:
		pass
	self.delay = 1.0
if timeout is not None:
	self.timeout = timeout
if loop:
	pass
]:
	i: 
	o: 232()

nname: 0
n 0(None)[if self.running:
	self.stop()
self.running = sched.ts
self._paused = None
if consider_idle is not None:
	self._considered_idle = consider_idle
if delay is None:
	delay = self.delay
if loop is None:
	if self.ival is None:
		pass
	loop = True
if delay is not None:
	if delay is not None:
		pass
	self.delay = 1.0
if timeout is not None:
	self.timeout = timeout
if loop:
	pass
self.ival = None
self._generator = self._generate()
if init_delay is not None:
	pass
sched.add(self, delay, self._generator)
return self
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16b7ec>}
nname: 56
n 56(None)[return None
]:
	i: 15(), 55()
	o: 

nname: 55
n 55(None)[]:
	i: 0(f)
	o: 56()

nname: 15
n 15(None)[self._paused = sched.ts - self.running
self.stop()
return self._paused
]:
	i: 0(t)
	o: 56()

nname: 0
n 0(self._paused is None)[]:
	i: 
	o: 15(t), 55(f)

nname: 0
n 0(None)[if self._paused is None:
	self._paused = sched.ts - self.running
	self.stop()
	return self._paused
return None
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e84c>}
nname: 98
n 98(None)[return None
]:
	i: 15(), 97()
	o: 

nname: 97
n 97(None)[]:
	i: 0(f)
	o: 98()

nname: 15
n 15(None)[self.running = sched.ts
self._generator = self._generate()
remaining = self.delay - self._paused
sched.add(self, remaining, self._generator)
self._paused = None
return remaining
]:
	i: 0(t)
	o: 98()

nname: 0
n 0(self._paused is not None)[]:
	i: 
	o: 15(t), 97(f)

nname: 0
n 0(None)[if self._paused is not None:
	self.running = sched.ts
	self._generator = self._generate()
	remaining = self.delay - self._paused
	sched.add(self, remaining, self._generator)
	self._paused = None
	return remaining
return None
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16afac>}
nname: 106
n 106(None)[return None
]:
	i: 80(), 105()
	o: 

nname: 105
n 105(None)[]:
	i: 0(f)
	o: 106()

nname: 80
n 80(None)[self._generator = None
sched.remove(self)
]:
	i: 28(), 55(), 78(AE)
	o: 106()

nname: 78
n 78(None)[]:
	i: 45(f)
	o: 80(AE)

nname: 55
n 55(None)[log.warning('%s has running timer!', self)
]:
	i: 45(t)
	o: 80()

nname: 45
n 45(<dummy_ex3> EXC_MATCH ValueError)[]:
	i: 24(except)
	o: 55(t), 78(f)

nname: 28
n 28(None)[self._generator.close()
]:
	i: 24(try)
	o: 80()

nname: 24
n 24(None)[]:
	i: 0(t)
	o: 28(try), 45(except)

nname: 0
n 0(self._generator is not None)[self.running = False
]:
	i: 
	o: 24(t), 105(f)

nname: 106
n 106(None)[return None
]:
	i: 45(), 0(f)
	o: 

nname: 45
n 45(None)[except ValueError:
	log.warning('%s has running timer!', self)
self._generator = None
sched.remove(self)
]:
	i: 24()
	o: 106()

nname: 24
n 24(None)[try:
	self._generator.close()
]:
	i: 0(t)
	o: 45()

nname: 0
n 0(self._generator is not None)[self.running = False
]:
	i: 
	o: 24(t), 106(f)

nname: 106
n 106(None)[return None
]:
	i: 24(), 0(f)
	o: 

nname: 24
n 24(None)[try:
	self._generator.close()
except ValueError:
	log.warning('%s has running timer!', self)
self._generator = None
sched.remove(self)
]:
	i: 0(t)
	o: 106()

nname: 0
n 0(self._generator is not None)[self.running = False
]:
	i: 
	o: 24(t), 106(f)

nname: 0
n 0(None)[self.running = False
if self._generator is not None:
	try:
		self._generator.close()
	except ValueError:
		log.warning('%s has running timer!', self)
	self._generator = None
	sched.remove(self)
return None
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e90c>}
nname: 182
n 182(None)[return None
]:
	i: 0(AL), 180()
	o: 

nname: 180
n 180(None)[]:
	i: 3(f), 168()
	o: 182()

nname: 168
n 168(None)[yield self.ival
]:
	i: 144(f), 159()
	o: 180()

nname: 159
n 159(None)[yield ret
continue
]:
	i: 144(t)
	o: 168()

nname: 144
n 144(ret.__class__ is float)[]:
	i: 143(AE)
	o: 159(t), 168(f)

nname: 143
n 143(None)[]:
	i: 133(), 142()
	o: 144(AE)

nname: 142
n 142(None)[]:
	i: 124(t)
	o: 143()

nname: 133
n 133(None)[yield None
]:
	i: 124(f)
	o: 143()

nname: 124
n 124(self.running)[]:
	i: 9(finally), 120()
	o: 133(f), 142(t)

nname: 120
n 120(None)[]:
	i: 22(), 60(), 79(), 118(AE)
	o: 124()

nname: 118
n 118(None)[]:
	i: 68(f)
	o: 120(AE)

nname: 79
n 79(None)[#, e
log.error('Task failed: %s: %s' % (self, e))
TRACE()
]:
	i: 68(t)
	o: 120()

nname: 68
n 68(<dummy_ex3> EXC_MATCH Exception)[]:
	i: 50(f)
	o: 79(t), 118(f)

nname: 60
n 60(None)[break
]:
	i: 50(t)
	o: 120()

nname: 50
n 50(<dummy_ex3> EXC_MATCH StopIteration)[]:
	i: 19(except)
	o: 60(t), 68(f)

nname: 22
n 22(None)[ret = self.fn(*self.args, **self.kw)
]:
	i: 19(try)
	o: 120()

nname: 19
n 19(None)[]:
	i: 9(ASF)
	o: 22(try), 50(except)

nname: 9
n 9(None)[ret = None
]:
	i: 3(t)
	o: 19(ASF2), 124(finally)

nname: 3
n 3(True)[]:
	i: 0(loop)
	o: 9(t), 180(f)

nname: 0
n 0(None)[]:
	i: 
	o: 3(loop), 182(AL)

nname: 182
n 182(None)[return None
]:
	i: 0(AL), 3(f), 144()
	o: 

nname: 144
n 144(None)[if ret.__class__ is float:
	yield ret
	continue
yield self.ival
]:
	i: 124(AE)
	o: 182()

nname: 124
n 124(None)[if not self.running:
	yield None
]:
	i: 9(finally), 50()
	o: 144(AE)

nname: 50
n 50(None)[except StopIteration:
	break
except:
	except Exception, e:
		log.error('Task failed: %s: %s' % (self, e))
		TRACE()
]:
	i: 19()
	o: 124()

nname: 19
n 19(None)[try:
	ret = self.fn(*self.args, **self.kw)
]:
	i: 9(ASF2)
	o: 50()

nname: 9
n 9(None)[ret = None
]:
	i: 3(t)
	o: 19(ASF2), 124(finally)

nname: 3
n 3(True)[]:
	i: 0(loop)
	o: 9(t), 182(f)

nname: 0
n 0(None)[]:
	i: 
	o: 3(loop), 182(AL)

nname: 182
n 182(None)[return None
]:
	i: 0(AL), 3(f), 144()
	o: 

nname: 144
n 144(None)[if ret.__class__ is float:
	yield ret
	continue
yield self.ival
]:
	i: 124(AE)
	o: 182()

nname: 124
n 124(None)[if not self.running:
	yield None
]:
	i: 9(finally), 19()
	o: 144(AE)

nname: 19
n 19(None)[try:
	ret = self.fn(*self.args, **self.kw)
except StopIteration:
	break
except:
	except Exception, e:
		log.error('Task failed: %s: %s' % (self, e))
		TRACE()
]:
	i: 9(ASF2)
	o: 124()

nname: 9
n 9(None)[ret = None
]:
	i: 3(t)
	o: 19(ASF2), 124(finally)

nname: 3
n 3(True)[]:
	i: 0(loop)
	o: 9(t), 182(f)

nname: 0
n 0(None)[]:
	i: 
	o: 3(loop), 182(AL)

nname: 182
n 182(None)[return None
]:
	i: 0(AL), 3(f), 124()
	o: 

nname: 124
n 124(None)[finally:
	if not self.running:
		yield None
if ret.__class__ is float:
	yield ret
	continue
yield self.ival
]:
	i: 9()
	o: 182()

nname: 9
n 9(None)[ret = None
try:
	ret = self.fn(*self.args, **self.kw)
except StopIteration:
	break
except:
	except Exception, e:
		log.error('Task failed: %s: %s' % (self, e))
		TRACE()
]:
	i: 3(t)
	o: 124()

nname: 3
n 3(True)[]:
	i: 0(loop)
	o: 9(t), 182(f)

nname: 0
n 0(None)[]:
	i: 
	o: 3(loop), 182(AL)

nname: 182
n 182(None)[return None
]:
	i: 0(AL), 3(f), 9()
	o: 

nname: 9
n 9(None)[ret = None
try:
	ret = self.fn(*self.args, **self.kw)
except StopIteration:
	break
except:
	except Exception, e:
		log.error('Task failed: %s: %s' % (self, e))
		TRACE()
finally:
	if not self.running:
		yield None
if ret.__class__ is float:
	yield ret
	continue
yield self.ival
]:
	i: 3(t)
	o: 182()

nname: 3
n 3(True)[]:
	i: 0(loop)
	o: 9(t), 182(f)

nname: 0
n 0(None)[]:
	i: 
	o: 3(loop), 182(AL)

nname: 9
n 9(None)[	ret = None
	try:
		ret = self.fn(*self.args, **self.kw)
	except StopIteration:
		break
	except:
		except Exception, e:
			log.error('Task failed: %s: %s' % (self, e))
			TRACE()
	finally:
		if not self.running:
			yield None
	if ret.__class__ is float:
		yield ret
		continue
	yield self.ival
return None
]:
	i: 0(t)
	o: 

nname: 0
n 0(True)[while True:
]:
	i: 
	o: 9(t)

nname: 0
n 0(None)[while True:
	ret = None
	try:
		ret = self.fn(*self.args, **self.kw)
	except StopIteration:
		break
	except:
		except Exception, e:
			log.error('Task failed: %s: %s' % (self, e))
			TRACE()
	finally:
		if not self.running:
			yield None
	if ret.__class__ is float:
		yield ret
		continue
	yield self.ival
return None
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16b92c>}
nname: 6
n 6(None)[__doc__ = "A schedulable task.\nInteresting properties:\n    running (bool): is the task running ?\n    delay: base delay (interval in loop mode)\n\nExemples:\n    # Will start task after 5s and then every second\n    task.start(1, loop=True, init_delay=5)\n\n    # Start a task & stop it before anything\n    t = Task(sys.stdout.write, 'Hello world\\n').start(5)\n    t.stop()\n\nImplementation Notes:\n    Two tasks started within the same task and with the same delay will\n    be scheduled for the *same* time be cause the reference time is the\n    begin of the current task.\n    The probability for another task to be executed between those two tasks is very very low.\n    "
__slots__ = ['args', 'kw', 'fn', 'running', 'timeout', 'delay', 'ival', '_paused', '_generator', '_considered_idle']
def __init__(self, fn, *args, **args):
	self.args = args
	self.kw = kw
	self.fn = fn
	self.ival = None
	self.running = False
	self.timeout = None
	self._generator = None
	self._considered_idle = False
	return None

def __repr__(self):
	if self.running:
		pass
	if self._considered_idle:
		pass
	if self.ival is None:
		pass
	return '<%s %s task %s calling %s>' % ('stopped', 'busy', 'every %ss' % self.ival, self.fn)

def start(self, delay=None, loop=None, timeout=None, init_delay=None, consider_idle=None):
	if self.running:
		self.stop()
	self.running = sched.ts
	self._paused = None
	if consider_idle is not None:
		self._considered_idle = consider_idle
	if delay is None:
		delay = self.delay
	if loop is None:
		if self.ival is None:
			pass
		loop = True
	if delay is not None:
		if delay is not None:
			pass
		self.delay = 1.0
	if timeout is not None:
		self.timeout = timeout
	if loop:
		pass
	self.ival = None
	self._generator = self._generate()
	if init_delay is not None:
		pass
	sched.add(self, delay, self._generator)
	return self

def pause(self):
	if self._paused is None:
		self._paused = sched.ts - self.running
		self.stop()
		return self._paused
	return None

def unpause(self):
	if self._paused is not None:
		self.running = sched.ts
		self._generator = self._generate()
		remaining = self.delay - self._paused
		sched.add(self, remaining, self._generator)
		self._paused = None
		return remaining
	return None

def stop(self):
	self.running = False
	if self._generator is not None:
		try:
			self._generator.close()
		except ValueError:
			log.warning('%s has running timer!', self)
		self._generator = None
		sched.remove(self)
	return None

def _generate(self):
	while True:
		ret = None
		try:
			ret = self.fn(*self.args, **self.kw)
		except StopIteration:
			break
		except:
			except Exception, e:
				log.error('Task failed: %s: %s' % (self, e))
				TRACE()
		finally:
			if not self.running:
				yield None
		if ret.__class__ is float:
			yield ret
			continue
		yield self.ival
	return None

]:
	i: 
	o: 

self.nodes: {6: <unpyclib.structure.node instance at 0xa16a96c>}
nname: 0
n 0(None)[threading.Thread.__init__(self)
self.completed = threading.Event()
self.started = threading.Event()
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16a76c>}
nname: 82
n 82(None)[]:
	i: 53(), 72()
	o: 

nname: 72
n 72(None)[self.on_success()
]:
	i: 3(), 70(AE)
	o: 82()

nname: 70
n 70(None)[]:
	i: 43(f)
	o: 72(AE)

nname: 53
n 53(None)[self.on_failure()
]:
	i: 43(t)
	o: 82()

nname: 43
n 43(<dummy_ex3> EXC_MATCH Exception)[]:
	i: 0(except)
	o: 53(t), 70(f)

nname: 3
n 3(None)[self.func_process()
self.completed.wait()
log.debug('completed set !')
]:
	i: 0(try)
	o: 72()

nname: 0
n 0(None)[]:
	i: 
	o: 3(try), 43(except)

nname: 82
n 82(None)[]:
	i: 53(), 72(), 43(f)
	o: 

nname: 53
n 53(None)[self.on_failure()
]:
	i: 43(t)
	o: 82()

nname: 43
n 43(<dummy_ex3> EXC_MATCH Exception)[]:
	i: 0(except)
	o: 53(t), 82(f)

nname: 72
n 72(None)[self.on_success()
]:
	i: 3(), 70(AE)
	o: 82()

nname: 3
n 3(None)[self.func_process()
self.completed.wait()
log.debug('completed set !')
]:
	i: 0(try)
	o: 72()

nname: 0
n 0(None)[]:
	i: 
	o: 3(try), 43(except)

nname: 82
n 82(None)[]:
	i: 43()
	o: 

nname: 43
n 43(None)[except Exception:
	self.on_failure()
else:
	self.on_success()
]:
	i: 0()
	o: 82()

nname: 0
n 0(None)[try:
	self.func_process()
	self.completed.wait()
	log.debug('completed set !')
]:
	i: 
	o: 43()

nname: 82
n 82(None)[]:
	i: 0()
	o: 

nname: 0
n 0(None)[try:
	self.func_process()
	self.completed.wait()
	log.debug('completed set !')
except Exception:
	self.on_failure()
else:
	self.on_success()
]:
	i: 
	o: 82()

nname: 0
n 0(None)[try:
	self.func_process()
	self.completed.wait()
	log.debug('completed set !')
except Exception:
	self.on_failure()
else:
	self.on_success()
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16ac2c>}
nname: 0
n 0(None)[raise NotImplementedError
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16ad4c>}
nname: 0
n 0(None)[]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16adcc>}
nname: 0
n 0(None)[log.debug(self)
self.completed.set()
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16ae8c>}
nname: 52
n 52(None)[]:
	i: 16(), 43(), 50(AE)
	o: 

nname: 50
n 50(None)[]:
	i: 33(f)
	o: 52(AE)

nname: 43
n 43(None)[]:
	i: 33(t)
	o: 52()

nname: 33
n 33(<dummy_ex3> EXC_MATCH AttributeError)[]:
	i: 0(except)
	o: 43(t), 50(f)

nname: 16
n 16(None)[self.controler.stop()
]:
	i: 0(try)
	o: 52()

nname: 0
n 0(None)[log.debug(self)
]:
	i: 
	o: 16(try), 33(except)

nname: 33
n 33(None)[except AttributeError:
	pass
]:
	i: 0()
	o: 

nname: 0
n 0(None)[log.debug(self)
try:
	self.controler.stop()
]:
	i: 
	o: 33()

nname: 0
n 0(None)[log.debug(self)
try:
	self.controler.stop()
except AttributeError:
	pass
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16ac2c>}
nname: 52
n 52(None)[]:
	i: 16(), 43(), 50(AE)
	o: 

nname: 50
n 50(None)[]:
	i: 33(f)
	o: 52(AE)

nname: 43
n 43(None)[]:
	i: 33(t)
	o: 52()

nname: 33
n 33(<dummy_ex3> EXC_MATCH AttributeError)[]:
	i: 0(except)
	o: 43(t), 50(f)

nname: 16
n 16(None)[self.controler.stop()
]:
	i: 0(try)
	o: 52()

nname: 0
n 0(None)[log.debug(self)
]:
	i: 
	o: 16(try), 33(except)

nname: 33
n 33(None)[except AttributeError:
	pass
]:
	i: 0()
	o: 

nname: 0
n 0(None)[log.debug(self)
try:
	self.controler.stop()
]:
	i: 
	o: 33()

nname: 0
n 0(None)[log.debug(self)
try:
	self.controler.stop()
except AttributeError:
	pass
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16aeac>}
nname: 6
n 6(None)[__doc__ = '\n    This class provide a Thread skeleton, typically in order\n    to be started by a ThreadedTask object.\n    The main method, which is executed in run() is func_process(), that MUST\n    be overriden.\n    Control methods are available, and are called when func_process succeded, or failed,\n    or is canceled, and to retrieve some infos\n    !!! In order to be canceled, func_process has to be asynchronous\n    '
def __init__(self):
	threading.Thread.__init__(self)
	self.completed = threading.Event()
	self.started = threading.Event()

def run(self):
	try:
		self.func_process()
		self.completed.wait()
		log.debug('completed set !')
	except Exception:
		self.on_failure()
	else:
		self.on_success()

def func_process(self, *args, **args):
	raise NotImplementedError

def get_infos(self):
	pass

def on_cancel(self):
	log.debug(self)
	self.completed.set()

def on_success(self):
	log.debug(self)
	try:
		self.controler.stop()
	except AttributeError:
		pass

def on_failure(self):
	log.debug(self)
	try:
		self.controler.stop()
	except AttributeError:
		pass

]:
	i: 
	o: 

self.nodes: {6: <unpyclib.structure.node instance at 0xa16a6ec>}
nname: 0
n 0(None)[Task.__init__(self, fn=None)
self.job = job
self.job.controler = self
self.fn = self._get_job_infos
return None
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16aecc>}
nname: 76
n 76(None)[return '<%s %s task %s getting infos from %s>' % ('stopped', 'busy', 'every %ss' % self.ival, self.__class__.__name__)
]:
	i: 58(), 65()
	o: 

nname: 65
n 65(None)[]:
	i: 43(f)
	o: 76()

nname: 58
n 58(None)[]:
	i: 43(t)
	o: 76()

nname: 43
n 43(self.ival is None)[]:
	i: 32(), 39()
	o: 58(t), 65(f)

nname: 39
n 39(None)[]:
	i: 23(f)
	o: 43()

nname: 32
n 32(None)[]:
	i: 23(t)
	o: 43()

nname: 23
n 23(self._considered_idle)[]:
	i: 12(), 19()
	o: 32(t), 39(f)

nname: 19
n 19(None)[]:
	i: 0(f)
	o: 23()

nname: 12
n 12(None)[]:
	i: 0(t)
	o: 23()

nname: 0
n 0(self.running)[]:
	i: 
	o: 12(t), 19(f)

nname: 43
n 43(None)[if self.ival is None:
	pass
return '<%s %s task %s getting infos from %s>' % ('stopped', 'busy', 'every %ss' % self.ival, self.__class__.__name__)
]:
	i: 0()
	o: 

nname: 0
n 0(None)[if self.running:
	pass
if self._considered_idle:
	pass
]:
	i: 
	o: 43()

nname: 0
n 0(None)[if self.running:
	pass
if self._considered_idle:
	pass
if self.ival is None:
	pass
return '<%s %s task %s getting infos from %s>' % ('stopped', 'busy', 'every %ss' % self.ival, self.__class__.__name__)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16b64c>}
nname: 0
n 0(None)[self.job.start()
Task.start(self, delay, loop, timeout, init_delay, consider_idle)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16aa6c>}
nname: 0
n 0(None)[]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16ab6c>}
nname: 0
n 0(None)[self.report_job_progress(self.job.get_infos())
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16a82c>}
nname: 0
n 0(None)[]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16a9ac>}
nname: 100
n 100(None)[]:
	i: 89(AE)
	o: 

nname: 89
n 89(None)[self.stop()
]:
	i: 0(finally), 85()
	o: 100(AE)

nname: 85
n 85(None)[]:
	i: 15(), 55(), 83(AE)
	o: 89()

nname: 83
n 83(None)[]:
	i: 45(f)
	o: 85(AE)

nname: 55
n 55(None)[#, e
log.error('Unable to cancel Thread %r <==%s==>', job, e)
]:
	i: 45(t)
	o: 85()

nname: 45
n 45(<dummy_ex3> EXC_MATCH Exception)[]:
	i: 12(except)
	o: 55(t), 83(f)

nname: 15
n 15(None)[job.on_cancel()
log.debug('Thread %r canceled', job)
]:
	i: 12(try)
	o: 85()

nname: 12
n 12(None)[]:
	i: 0(ASF)
	o: 15(try), 45(except)

nname: 0
n 0(None)[job = self.job
]:
	i: 
	o: 12(ASF2), 89(finally)

nname: 100
n 100(None)[]:
	i: 89(AE)
	o: 

nname: 89
n 89(None)[self.stop()
]:
	i: 0(finally), 45()
	o: 100(AE)

nname: 45
n 45(None)[except Exception, e:
	log.error('Unable to cancel Thread %r <==%s==>', job, e)
]:
	i: 12()
	o: 89()

nname: 12
n 12(None)[try:
	job.on_cancel()
	log.debug('Thread %r canceled', job)
]:
	i: 0(ASF2)
	o: 45()

nname: 0
n 0(None)[job = self.job
]:
	i: 
	o: 12(ASF2), 89(finally)

nname: 100
n 100(None)[]:
	i: 89(AE)
	o: 

nname: 89
n 89(None)[self.stop()
]:
	i: 0(finally), 12()
	o: 100(AE)

nname: 12
n 12(None)[try:
	job.on_cancel()
	log.debug('Thread %r canceled', job)
except Exception, e:
	log.error('Unable to cancel Thread %r <==%s==>', job, e)
]:
	i: 0(ASF2)
	o: 89()

nname: 0
n 0(None)[job = self.job
]:
	i: 
	o: 12(ASF2), 89(finally)

nname: 89
n 89(None)[finally:
	self.stop()
]:
	i: 0()
	o: 

nname: 0
n 0(None)[job = self.job
try:
	job.on_cancel()
	log.debug('Thread %r canceled', job)
except Exception, e:
	log.error('Unable to cancel Thread %r <==%s==>', job, e)
]:
	i: 
	o: 89()

nname: 0
n 0(None)[job = self.job
try:
	job.on_cancel()
	log.debug('Thread %r canceled', job)
except Exception, e:
	log.error('Unable to cancel Thread %r <==%s==>', job, e)
finally:
	self.stop()
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16b66c>}
nname: 0
n 0(None)[self.on_terminate()
Task.stop(self)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16ae4c>}
nname: 6
n 6(None)[__doc__ = '\n    This class provides a Task that mainly do 2 things :\n        - start the HookThread object passed in parameters and control it\n        - retrieves infos on this HookThread and report them via progress method()\n    '
def __init__(self, job, *args, **args):
	Task.__init__(self, fn=None)
	self.job = job
	self.job.controler = self
	self.fn = self._get_job_infos
	return None

def __repr__(self):
	if self.running:
		pass
	if self._considered_idle:
		pass
	if self.ival is None:
		pass
	return '<%s %s task %s getting infos from %s>' % ('stopped', 'busy', 'every %ss' % self.ival, self.__class__.__name__)

def start(self, delay=None, loop=True, timeout=None, init_delay=None, consider_idle=None):
	self.job.start()
	Task.start(self, delay, loop, timeout, init_delay, consider_idle)

def report_job_progress(self, infos_dict):
	pass

def _get_job_infos(self):
	self.report_job_progress(self.job.get_infos())

def on_terminate(self):
	pass

def cancel(self):
	job = self.job
	try:
		job.on_cancel()
		log.debug('Thread %r canceled', job)
	except Exception, e:
		log.error('Unable to cancel Thread %r <==%s==>', job, e)
	finally:
		self.stop()

def stop(self):
	self.on_terminate()
	Task.stop(self)

]:
	i: 
	o: 

self.nodes: {6: <unpyclib.structure.node instance at 0xa16ad8c>}
nname: 0
n 0(None)[self._indexed_tasks = {}
self._global_tasks = collections.defaultdict(dict)
self.add('clock', self.global_clock, delay=1, loop=True, consider_idle=True)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16b2ac>}
nname: 0
n 0(None)[return self._global_tasks[self._indexed_tasks[task_name]]
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16accc>}
nname: 0
n 0(None)[self.callbacks_by_task(task_name)[obs] = (args, kw)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16af0c>}
nname: 0
n 0(None)[self.callbacks_by_task(task_name).pop(obs)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16aa2c>}
nname: 0
n 0(None)[log.debug('GlobalTimer: %s' % task_name)
ret = fn(*args, **kwargs)
self._dispatch(task_name, ret)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e40c>}
nname: 129
n 129(None)[self._indexed_tasks[task_name] = t
self._global_tasks[t] = {}
t.start(delay, loop, timeout, init_delay, consider_idle)
return None
]:
	i: 65(), 110()
	o: 

nname: 110
n 110(None)[t = Task(self._dispatch, task_name)
]:
	i: 0(f)
	o: 129()

nname: 65
n 65(None)[kwargs = {}
def _fn():
	log.debug('GlobalTimer: %s' % task_name)
	ret = fn(*args, **kwargs)
	self._dispatch(task_name, ret)

t = Task(_fn)
]:
	i: 54(), 61()
	o: 129()

nname: 61
n 61(None)[]:
	i: 39(f)
	o: 65()

nname: 54
n 54(None)[]:
	i: 39(t)
	o: 65()

nname: 39
n 39(kwargs is not None)[args = tuple()
]:
	i: 25(), 32()
	o: 54(t), 61(f)

nname: 32
n 32(None)[]:
	i: 12(f)
	o: 39()

nname: 25
n 25(None)[]:
	i: 12(t)
	o: 39()

nname: 12
n 12(args is not None)[]:
	i: 0(t)
	o: 25(t), 32(f)

nname: 0
n 0(fn is not None)[]:
	i: 
	o: 12(t), 110(f)

nname: 129
n 129(None)[self._indexed_tasks[task_name] = t
self._global_tasks[t] = {}
t.start(delay, loop, timeout, init_delay, consider_idle)
return None
]:
	i: 65(), 110()
	o: 

nname: 110
n 110(None)[t = Task(self._dispatch, task_name)
]:
	i: 0(f)
	o: 129()

nname: 65
n 65(None)[kwargs = {}
def _fn():
	log.debug('GlobalTimer: %s' % task_name)
	ret = fn(*args, **kwargs)
	self._dispatch(task_name, ret)

t = Task(_fn)
]:
	i: 12()
	o: 129()

nname: 12
n 12(None)[if args is not None:
	pass
args = tuple()
if kwargs is not None:
	pass
]:
	i: 0(t)
	o: 65()

nname: 0
n 0(fn is not None)[]:
	i: 
	o: 12(t), 110(f)

nname: 129
n 129(None)[self._indexed_tasks[task_name] = t
self._global_tasks[t] = {}
t.start(delay, loop, timeout, init_delay, consider_idle)
return None
]:
	i: 12(), 110()
	o: 

nname: 110
n 110(None)[t = Task(self._dispatch, task_name)
]:
	i: 0(f)
	o: 129()

nname: 12
n 12(None)[if args is not None:
	pass
args = tuple()
if kwargs is not None:
	pass
kwargs = {}
def _fn():
	log.debug('GlobalTimer: %s' % task_name)
	ret = fn(*args, **kwargs)
	self._dispatch(task_name, ret)

t = Task(_fn)
]:
	i: 0(t)
	o: 129()

nname: 0
n 0(fn is not None)[]:
	i: 
	o: 12(t), 110(f)

nname: 0
n 0(None)[if fn is not None:
	if args is not None:
		pass
	args = tuple()
	if kwargs is not None:
		pass
	kwargs = {}
	def _fn():
		log.debug('GlobalTimer: %s' % task_name)
		ret = fn(*args, **kwargs)
		self._dispatch(task_name, ret)

	t = Task(_fn)
else:
	t = Task(self._dispatch, task_name)
self._indexed_tasks[task_name] = t
self._global_tasks[t] = {}
t.start(delay, loop, timeout, init_delay, consider_idle)
return None
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16b0ac>}
nname: 0
n 0(None)[t = self._indexed_tasks.pop(task_name)
t.stop()
self._global_tasks.pop(t)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16ab2c>}
nname: 36
n 36(None)[self._indexed_tasks.clear()
self._global_tasks.clear()
]:
	i: 0(AL), 35()
	o: 

nname: 35
n 35(None)[]:
	i: 3(AF), 19()
	o: 36()

nname: 19
n 19(None)[for task in self._indexed_tasks.itervalues():
task.stop()
]:
	i: 3(for)
	o: 35()

nname: 3
n 3(None)[]:
	i: 0(loop)
	o: 19(for), 35(AF)

nname: 0
n 0(None)[]:
	i: 
	o: 3(loop), 36(AL)

nname: 36
n 36(None)[self._indexed_tasks.clear()
self._global_tasks.clear()
]:
	i: 19()
	o: 

nname: 19
n 19(None)[for task in self._indexed_tasks.itervalues():
	task.stop()
]:
	i: 0(for)
	o: 36()

nname: 0
n 0(None)[]:
	i: 
	o: 19(for)

nname: 36
n 36(None)[self._indexed_tasks.clear()
self._global_tasks.clear()
]:
	i: 0()
	o: 

nname: 0
n 0(None)[for task in self._indexed_tasks.itervalues():
	task.stop()
]:
	i: 
	o: 36()

nname: 0
n 0(None)[for task in self._indexed_tasks.itervalues():
	task.stop()
self._indexed_tasks.clear()
self._global_tasks.clear()
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16b94c>}
nname: 107
n 107(None)[return None
]:
	i: 0(AL), 106()
	o: 

nname: 106
n 106(None)[]:
	i: 20(AF), 89()
	o: 107()

nname: 89
n 89(None)[obs(*args, **kw)
]:
	i: 42(f), 69()
	o: 106()

nname: 69
n 69(None)[obs(ret, *args, **kw)
continue
]:
	i: 42(t)
	o: 89()

nname: 42
n 42(ret is not None)[for obs, args in self.callbacks_by_task(task_name).iteritems():
]:
	i: 20(for)
	o: 69(t), 89(f)

nname: 20
n 20(None)[]:
	i: 0(loop)
	o: 42(for), 106(AF)

nname: 0
n 0(None)[log.debug('GlobalTimer: %s' % task_name)
]:
	i: 
	o: 20(loop), 107(AL)

nname: 107
n 107(None)[return None
]:
	i: 0(AL), 20(AF), 42()
	o: 

nname: 42
n 42(None)[for obs, args in self.callbacks_by_task(task_name).iteritems():
if ret is not None:
	obs(ret, *args, **kw)
	continue
obs(*args, **kw)
]:
	i: 20(for)
	o: 107()

nname: 20
n 20(None)[]:
	i: 0(loop)
	o: 42(for), 107(AF)

nname: 0
n 0(None)[log.debug('GlobalTimer: %s' % task_name)
]:
	i: 
	o: 20(loop), 107(AL)

nname: 42
n 42(None)[for obs, args in self.callbacks_by_task(task_name).iteritems():
	if ret is not None:
		obs(ret, *args, **kw)
		continue
	obs(*args, **kw)
return None
]:
	i: 0(for)
	o: 

nname: 0
n 0(None)[log.debug('GlobalTimer: %s' % task_name)
]:
	i: 
	o: 42(for)

nname: 0
n 0(None)[log.debug('GlobalTimer: %s' % task_name)
for obs, args in self.callbacks_by_task(task_name).iteritems():
	if ret is not None:
		obs(ret, *args, **kw)
		continue
	obs(*args, **kw)
return None
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16bccc>}
nname: 0
n 0(None)[return _time.time()
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16ab0c>}
nname: 6
n 6(None)[__doc__ = '\n    GlobalTimer is in charge to handle global tasks in notifier.\n    Tasks can be added and are accesible by a simple name.\n    Callbacks can be registered, and so executed each time the task ticks.\n    '
def __init__(self):
	self._indexed_tasks = {}
	self._global_tasks = collections.defaultdict(dict)
	self.add('clock', self.global_clock, delay=1, loop=True, consider_idle=True)

def callbacks_by_task(self, task_name):
	return self._global_tasks[self._indexed_tasks[task_name]]

def register_callback(self, task_name, obs, *args, **args):
	self.callbacks_by_task(task_name)[obs] = (args, kw)

def unregister_callback(self, task_name, obs):
	self.callbacks_by_task(task_name).pop(obs)

def add(self, task_name, fn=None, args=None, kwargs=None, delay=0, loop=None, timeout=None, init_delay=None, consider_idle=None):
	if fn is not None:
		if args is not None:
			pass
		args = tuple()
		if kwargs is not None:
			pass
		kwargs = {}
		def _fn():
			log.debug('GlobalTimer: %s' % task_name)
			ret = fn(*args, **kwargs)
			self._dispatch(task_name, ret)

		t = Task(_fn)
	else:
		t = Task(self._dispatch, task_name)
	self._indexed_tasks[task_name] = t
	self._global_tasks[t] = {}
	t.start(delay, loop, timeout, init_delay, consider_idle)
	return None

def remove(self, task_name):
	t = self._indexed_tasks.pop(task_name)
	t.stop()
	self._global_tasks.pop(t)

def stop(self):
	for task in self._indexed_tasks.itervalues():
		task.stop()
	self._indexed_tasks.clear()
	self._global_tasks.clear()

def _dispatch(self, task_name, ret=None):
	log.debug('GlobalTimer: %s' % task_name)
	for obs, args in self.callbacks_by_task(task_name).iteritems():
		if ret is not None:
			obs(ret, *args, **kw)
			continue
		obs(*args, **kw)
	return None

def global_clock(self):
	return _time.time()

]:
	i: 
	o: 

self.nodes: {6: <unpyclib.structure.node instance at 0xa16acec>}
nname: 0
n 0(None)[return []
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16ba8c>}
nname: 0
n 0(None)[return []
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16b88c>}
nname: 0
n 0(None)[self.ts = time()
self._tasks = []
self.granularity = 0.01
self._rfds = collections.defaultdict((lambda : []))
self._idle_infos = dict(threshold=10, on_enter=None, on_exit=None, running=False)
return None
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16a70c>}
nname: 0
n 0(None)[heappush(self._tasks, (self.ts + ival - self.granularity, task, gen))
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16a9ac>}
nname: 140
n 140(None)[]:
	i: 123(), 139()
	o: 

nname: 139
n 139(None)[]:
	i: 77(f)
	o: 140()

nname: 123
n 123(None)[heapify(self._tasks)
]:
	i: 83(AL), 122()
	o: 140()

nname: 122
n 122(None)[]:
	i: 87(AF), 100()
	o: 123()

nname: 100
n 100(None)[for f in reversed(_found):
self._tasks.pop(f)
]:
	i: 87(for)
	o: 122()

nname: 87
n 87(None)[]:
	i: 83(loop)
	o: 100(for), 122(AF)

nname: 83
n 83(None)[]:
	i: 77(t)
	o: 87(loop), 123(AL)

nname: 77
n 77(_found)[]:
	i: 0(AL), 76()
	o: 83(t), 139(f)

nname: 76
n 76(None)[]:
	i: 9(AF), 72()
	o: 77()

nname: 72
n 72(None)[]:
	i: 25(f), 55()
	o: 76()

nname: 55
n 55(None)[_found.append(i)
continue
]:
	i: 25(t)
	o: 72()

nname: 25
n 25(t is task)[for i, tm in enumerate(self._tasks):
]:
	i: 9(for)
	o: 55(t), 72(f)

nname: 9
n 9(None)[]:
	i: 0(loop)
	o: 25(for), 76(AF)

nname: 0
n 0(None)[_found = []
]:
	i: 
	o: 9(loop), 77(AL)

nname: 140
n 140(None)[]:
	i: 123(), 77(f)
	o: 

nname: 123
n 123(None)[heapify(self._tasks)
]:
	i: 100()
	o: 140()

nname: 100
n 100(None)[for f in reversed(_found):
	self._tasks.pop(f)
]:
	i: 83(for)
	o: 123()

nname: 83
n 83(None)[]:
	i: 77(t)
	o: 100(for)

nname: 77
n 77(_found)[]:
	i: 0(AL), 9(AF), 25()
	o: 83(t), 140(f)

nname: 25
n 25(None)[for i, tm in enumerate(self._tasks):
if t is task:
	_found.append(i)
	continue
]:
	i: 9(for)
	o: 77()

nname: 9
n 9(None)[]:
	i: 0(loop)
	o: 25(for), 77(AF)

nname: 0
n 0(None)[_found = []
]:
	i: 
	o: 9(loop), 77(AL)

nname: 140
n 140(None)[]:
	i: 123(), 25(f)
	o: 

nname: 123
n 123(None)[heapify(self._tasks)
]:
	i: 83()
	o: 140()

nname: 83
n 83(None)[for f in reversed(_found):
	self._tasks.pop(f)
]:
	i: 25(t)
	o: 123()

nname: 25
n 25(_found)[for i, tm in enumerate(self._tasks):
	if t is task:
		_found.append(i)
		continue
]:
	i: 0(for)
	o: 83(t), 140(f)

nname: 0
n 0(None)[_found = []
]:
	i: 
	o: 25(for)

nname: 140
n 140(None)[]:
	i: 83(), 0(f)
	o: 

nname: 83
n 83(None)[for f in reversed(_found):
	self._tasks.pop(f)
heapify(self._tasks)
]:
	i: 0(t)
	o: 140()

nname: 0
n 0(_found)[_found = []
for i, tm in enumerate(self._tasks):
	if t is task:
		_found.append(i)
		continue
]:
	i: 
	o: 83(t), 140(f)

nname: 0
n 0(None)[_found = []
for i, tm in enumerate(self._tasks):
	if t is task:
		_found.append(i)
		continue
if _found:
	for f in reversed(_found):
		self._tasks.pop(f)
	heapify(self._tasks)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16af6c>}
nname: 0
n 0(None)[self._running = False
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16adcc>}
nname: 710
n 710(None)[return None
]:
	i: 0(AL), 708()
	o: 

nname: 708
n 708(None)[]:
	i: 54(f), 705()
	o: 710()

nname: 705
n 705(None)[]:
	i: 162(JA), 314(JA), 335(JA), 602(JA), 704()
	o: 708()

nname: 704
n 704(None)[]:
	i: 622&642(f), 688()
	o: 705()

nname: 688
n 688(None)[self._idle_infos['running'] = False
continue
]:
	i: 676(), 687()
	o: 704()

nname: 687
n 687(None)[]:
	i: 656(f)
	o: 688()

nname: 676
n 676(None)[cb()
]:
	i: 656(t)
	o: 688()

nname: 656
n 656(cb)[cb = self._idle_infos['on_exit']
]:
	i: 622&642(t)
	o: 676(t), 687(f)

nname: 622&642
n 622&642(idle_value < self._idle_infos['threshold'] and self._idle_infos['running'])[]:
	i: 518(t), 618()
	o: 656(t), 704(f)

nname: 618
n 618(None)[continue
]:
	i: 550(f)
	o: 622&642()

nname: 602
n 602(None)[self._idle_infos['running'] = True
]:
	i: 590(), 601()
	o: 705(JA)

nname: 601
n 601(None)[]:
	i: 570(f)
	o: 602()

nname: 590
n 590(None)[cb()
]:
	i: 570(t)
	o: 602()

nname: 570
n 570(cb)[cb = self._idle_infos['on_enter']
]:
	i: 550(t)
	o: 590(t), 601(f)

nname: 550
n 550(self._idle_infos['threshold'] <= idle_value)[]:
	i: 518(f)
	o: 570(t), 618(f)

nname: 518
n 518(self._idle_infos['running'])[idle_value = int(self.ts - idle_since)
]:
	i: 457(), 499(JA), 509(), 516(AE)
	o: 550(f), 622&642(t)

nname: 516
n 516(None)[]:
	i: 461(f)
	o: 518(AE)

nname: 509
n 509(None)[continue
]:
	i: 474(f)
	o: 518()

nname: 499
n 499(None)[raise v
]:
	i: 474(t)
	o: 518(JA)

nname: 474
n 474(v[0] != errno.EINTR)[#, v
]:
	i: 461(t)
	o: 499(t), 509(f)

nname: 461
n 461(<dummy_ex3> EXC_MATCH select.error)[]:
	i: 374(except)
	o: 474(t), 516(f)

nname: 457
n 457(None)[]:
	i: 378(AL), 456()
	o: 518()

nname: 456
n 456(None)[]:
	i: 381(AF), 453()
	o: 457()

nname: 453
n 453(None)[]:
	i: 419(AL), 452()
	o: 456()

nname: 452
n 452(None)[]:
	i: 425(AF), 439()
	o: 453()

nname: 439
n 439(None)[for r in self._rfds[rfd]:
r()
]:
	i: 425(for)
	o: 452()

nname: 425
n 425(None)[]:
	i: 419(loop)
	o: 439(for), 452(AF)

nname: 419
n 419(None)[for rfd in select.select(self._rfds.keys(), empty_list, empty_list, delta)[0]:
]:
	i: 381(for)
	o: 425(loop), 453(AL)

nname: 381
n 381(None)[]:
	i: 378(loop)
	o: 419(for), 456(AF)

nname: 378
n 378(None)[]:
	i: 374(try)
	o: 381(loop), 457(AL)

nname: 374
n 374(None)[]:
	i: 63&82(f), 361()
	o: 378(try), 461(except)

nname: 361
n 361(None)[task.running = False
continue
]:
	i: 323(f)
	o: 374()

nname: 335
n 335(None)[sched.add(task, ival, task._generator)
]:
	i: 323(t)
	o: 705(JA)

nname: 323
n 323(ival is not None)[]:
	i: 245(), 321(AE)
	o: 335(t), 361(f)

nname: 321
n 321(None)[]:
	i: 304(f)
	o: 323(AE)

nname: 314
n 314(None)[]:
	i: 304(t)
	o: 705(JA)

nname: 304
n 304(<dummy_ex3> EXC_MATCH StopIteration)[]:
	i: 195(except)
	o: 314(t), 321(f)

nname: 245
n 245(None)[log.info('TASK> %s', task)
ival = generator.next()
log.info('<TASK done in %.3ss' % (time() - self.ts))
]:
	i: 231(), 244()
	o: 323()

nname: 244
n 244(None)[]:
	i: 222(t)
	o: 245()

nname: 231
n 231(None)[idle_since = self.ts
]:
	i: 222(f)
	o: 245()

nname: 222
n 222(task._considered_idle)[]:
	i: 208(), 221()
	o: 231(f), 244(t)

nname: 221
n 221(None)[]:
	i: 199(t)
	o: 222()

nname: 208
n 208(None)[raise StopIteration()
]:
	i: 199(f)
	o: 222()

nname: 199
n 199(task.running)[]:
	i: 195(try)
	o: 208(f), 221(t)

nname: 195
n 195(None)[]:
	i: 106&143(f)
	o: 199(try), 304(except)

nname: 162
n 162(None)[log.warn('Dropped task: %s (+%s)', task, self.ts - task.timeout)
]:
	i: 106&143(t)
	o: 705(JA)

nname: 106&143
n 106&143(task.timeout is not None and self.ts > task.timeout)[delay, task, generator = heappop(tasks)
]:
	i: 63&82(t)
	o: 162(t), 195(f)

nname: 63&82
n 63&82(tasks and tasks[0][0] < self.ts)[self.ts = time()
]:
	i: 54(t)
	o: 106&143(t), 374(f)

nname: 54
n 54(self._running)[]:
	i: 0(loop)
	o: 63&82(t), 708(f)

nname: 0
n 0(None)[tasks = self._tasks
delta = self.granularity
add = self.add
self._running = True
empty_list = []
idle_since = self.ts
]:
	i: 
	o: 54(loop), 710(AL)

nname: 710
n 710(None)[return None
]:
	i: 0(AL), 54(f), 162(JA), 335(JA), 570(JA), 304(f), 304(t), 622&642(f), 656()
	o: 

nname: 656
n 656(None)[cb = self._idle_infos['on_exit']
if cb:
	cb()
self._idle_infos['running'] = False
continue
]:
	i: 622&642(t)
	o: 710()

nname: 622&642
n 622&642(idle_value < self._idle_infos['threshold'] and self._idle_infos['running'])[]:
	i: 518(t), 618()
	o: 656(t), 710(f)

nname: 618
n 618(None)[continue
]:
	i: 550(f)
	o: 622&642()

nname: 570
n 570(None)[cb = self._idle_infos['on_enter']
if cb:
	cb()
self._idle_infos['running'] = True
]:
	i: 550(t)
	o: 710(JA)

nname: 550
n 550(self._idle_infos['threshold'] <= idle_value)[]:
	i: 518(f)
	o: 570(t), 618(f)

nname: 518
n 518(self._idle_infos['running'])[idle_value = int(self.ts - idle_since)
]:
	i: 461(JA), 374(AL), 381(AF), 439()
	o: 550(f), 622&642(t)

nname: 461
n 461(None)[except select.error, v:
	if v[0] != errno.EINTR:
		raise v
	else:
		continue
]:
	i: 374()
	o: 518(JA)

nname: 518
n 518(self._idle_infos['running'])[idle_value = int(self.ts - idle_since)
]:
	i: 461(JA), 374(AL), 381(AF), 439()
	o: 550(f), 622&642(t)

nname: 439
n 439(None)[for r in self._rfds[rfd]:
	r()
]:
	i: 419(for)
	o: 518()

nname: 419
n 419(None)[for rfd in select.select(self._rfds.keys(), empty_list, empty_list, delta)[0]:
]:
	i: 381(for)
	o: 439(for)

nname: 381
n 381(None)[]:
	i: 374(loop)
	o: 419(for), 518(AF)

nname: 374
n 374(None)[try:
]:
	i: 63&82(f), 361()
	o: 381(loop), 518(AL), 461()

nname: 304
n 304(<dummy_ex3> EXC_MATCH StopIteration)[]:
	i: 195(except)
	o: 710(f)

nname: 361
n 361(None)[task.running = False
continue
]:
	i: 323(f)
	o: 374()

nname: 335
n 335(None)[sched.add(task, ival, task._generator)
]:
	i: 323(t)
	o: 710(JA)

nname: 323
n 323(ival is not None)[]:
	i: 245(), 321(AE)
	o: 335(t), 361(f)

nname: 245
n 245(None)[log.info('TASK> %s', task)
ival = generator.next()
log.info('<TASK done in %.3ss' % (time() - self.ts))
]:
	i: 199()
	o: 323()

nname: 199
n 199(None)[if not task.running:
	raise StopIteration()
if not task._considered_idle:
	idle_since = self.ts
]:
	i: 195(try)
	o: 245()

nname: 195
n 195(None)[]:
	i: 106&143(f)
	o: 199(try), 304(except)

structureSingleExcept Exception 'NoneType' object has no attribute 'toNode'
nname: 162
n 162(None)[log.warn('Dropped task: %s (+%s)', task, self.ts - task.timeout)
]:
	i: 106&143(t)
	o: 710(JA)

nname: 106&143
n 106&143(task.timeout is not None and self.ts > task.timeout)[delay, task, generator = heappop(tasks)
]:
	i: 63&82(t)
	o: 162(t), 195(f)

nname: 63&82
n 63&82(tasks and tasks[0][0] < self.ts)[self.ts = time()
]:
	i: 54(t)
	o: 106&143(t), 374(f)

nname: 54
n 54(self._running)[]:
	i: 0(loop)
	o: 63&82(t), 710(f)

nname: 0
n 0(None)[tasks = self._tasks
delta = self.granularity
add = self.add
self._running = True
empty_list = []
idle_since = self.ts
]:
	i: 
	o: 54(loop), 710(AL)

nname: 710
n 710(None)[return None
]:
	i: 0(AL), 54(f), 162(JA), 335(JA), 570(JA), 304(t), 622&642(f), 195(except)
	o: 

nname: 622&642
n 622&642(None)[if idle_value < self._idle_infos['threshold'] and self._idle_infos['running']:
	cb = self._idle_infos['on_exit']
	if cb:
		cb()
	self._idle_infos['running'] = False
	continue
]:
	i: 518(t), 618()
	o: 710()

nname: 618
n 618(None)[continue
]:
	i: 550(f)
	o: 622&642()

nname: 570
n 570(None)[cb = self._idle_infos['on_enter']
if cb:
	cb()
self._idle_infos['running'] = True
]:
	i: 550(t)
	o: 710(JA)

nname: 550
n 550(self._idle_infos['threshold'] <= idle_value)[]:
	i: 518(f)
	o: 570(t), 618(f)

nname: 518
n 518(self._idle_infos['running'])[idle_value = int(self.ts - idle_since)
]:
	i: 461(JA), 374(AL), 381(AF), 419()
	o: 550(f), 622&642(t)

nname: 461
n 461(None)[except select.error, v:
	if v[0] != errno.EINTR:
		raise v
	else:
		continue
]:
	i: 374()
	o: 518(JA)

nname: 518
n 518(self._idle_infos['running'])[idle_value = int(self.ts - idle_since)
]:
	i: 461(JA), 374(AL), 381(AF), 419()
	o: 550(f), 622&642(t)

nname: 419
n 419(None)[for rfd in select.select(self._rfds.keys(), empty_list, empty_list, delta)[0]:
for r in self._rfds[rfd]:
	r()
]:
	i: 381(for)
	o: 518()

nname: 381
n 381(None)[]:
	i: 374(loop)
	o: 419(for), 518(AF)

nname: 374
n 374(None)[try:
]:
	i: 63&82(f), 361()
	o: 381(loop), 518(AL), 461()

nname: 361
n 361(None)[task.running = False
continue
]:
	i: 323(f)
	o: 374()

nname: 335
n 335(None)[sched.add(task, ival, task._generator)
]:
	i: 323(t)
	o: 710(JA)

nname: 323
n 323(ival is not None)[]:
	i: 199(), 321(AE)
	o: 335(t), 361(f)

nname: 199
n 199(None)[if not task.running:
	raise StopIteration()
if not task._considered_idle:
	idle_since = self.ts
log.info('TASK> %s', task)
ival = generator.next()
log.info('<TASK done in %.3ss' % (time() - self.ts))
]:
	i: 195(try)
	o: 323()

nname: 195
n 195(None)[]:
	i: 106&143(f)
	o: 199(try), 710(except)

nname: 162
n 162(None)[log.warn('Dropped task: %s (+%s)', task, self.ts - task.timeout)
]:
	i: 106&143(t)
	o: 710(JA)

nname: 106&143
n 106&143(task.timeout is not None and self.ts > task.timeout)[delay, task, generator = heappop(tasks)
]:
	i: 63&82(t)
	o: 162(t), 195(f)

nname: 63&82
n 63&82(tasks and tasks[0][0] < self.ts)[self.ts = time()
]:
	i: 54(t)
	o: 106&143(t), 374(f)

nname: 54
n 54(self._running)[]:
	i: 0(loop)
	o: 63&82(t), 710(f)

nname: 0
n 0(None)[tasks = self._tasks
delta = self.granularity
add = self.add
self._running = True
empty_list = []
idle_since = self.ts
]:
	i: 
	o: 54(loop), 710(AL)

nname: 710
n 710(None)[except:
	return None
]:
	i: 0(AL), 54(f), 162(JA), 335(JA), 570(JA), 304(t), 622&642(f), 195(except)
	o: 

nname: 622&642
n 622&642(None)[if idle_value < self._idle_infos['threshold'] and self._idle_infos['running']:
	cb = self._idle_infos['on_exit']
	if cb:
		cb()
	self._idle_infos['running'] = False
	continue
]:
	i: 518(t), 618()
	o: 710()

nname: 618
n 618(None)[continue
]:
	i: 550(f)
	o: 622&642()

nname: 570
n 570(None)[cb = self._idle_infos['on_enter']
if cb:
	cb()
self._idle_infos['running'] = True
]:
	i: 550(t)
	o: 710(JA)

nname: 550
n 550(self._idle_infos['threshold'] <= idle_value)[]:
	i: 518(f)
	o: 570(t), 618(f)

nname: 518
n 518(self._idle_infos['running'])[idle_value = int(self.ts - idle_since)
]:
	i: 461(JA), 374(AL), 381(AF), 419()
	o: 550(f), 622&642(t)

nname: 461
n 461(None)[except select.error, v:
	if v[0] != errno.EINTR:
		raise v
	else:
		continue
]:
	i: 374()
	o: 518(JA)

nname: 518
n 518(self._idle_infos['running'])[idle_value = int(self.ts - idle_since)
]:
	i: 461(JA), 374(AL), 381(AF), 419()
	o: 550(f), 622&642(t)

nname: 419
n 419(None)[for rfd in select.select(self._rfds.keys(), empty_list, empty_list, delta)[0]:
for r in self._rfds[rfd]:
	r()
]:
	i: 381(for)
	o: 518()

nname: 381
n 381(None)[]:
	i: 374(loop)
	o: 419(for), 518(AF)

nname: 374
n 374(None)[try:
]:
	i: 63&82(f), 361()
	o: 381(loop), 518(AL), 461()

nname: 361
n 361(None)[task.running = False
continue
]:
	i: 323(f)
	o: 374()

nname: 335
n 335(None)[sched.add(task, ival, task._generator)
]:
	i: 323(t)
	o: 710(JA)

nname: 323
n 323(ival is not None)[]:
	i: 199(), 321(AE)
	o: 335(t), 361(f)

nname: 199
n 199(None)[if not task.running:
	raise StopIteration()
if not task._considered_idle:
	idle_since = self.ts
log.info('TASK> %s', task)
ival = generator.next()
log.info('<TASK done in %.3ss' % (time() - self.ts))
]:
	i: 195(try)
	o: 323()

nname: 195
n 195(None)[]:
	i: 106&143(f)
	o: 199(try), 710(except)

nname: 162
n 162(None)[log.warn('Dropped task: %s (+%s)', task, self.ts - task.timeout)
]:
	i: 106&143(t)
	o: 710(JA)

nname: 106&143
n 106&143(task.timeout is not None and self.ts > task.timeout)[delay, task, generator = heappop(tasks)
]:
	i: 63&82(t)
	o: 162(t), 195(f)

nname: 63&82
n 63&82(tasks and tasks[0][0] < self.ts)[self.ts = time()
]:
	i: 54(t)
	o: 106&143(t), 374(f)

nname: 54
n 54(self._running)[]:
	i: 0(loop)
	o: 63&82(t), 710(f)

nname: 0
n 0(None)[tasks = self._tasks
delta = self.granularity
add = self.add
self._running = True
empty_list = []
idle_since = self.ts
]:
	i: 
	o: 54(loop), 710(AL)

self.nodes: {0: <unpyclib.structure.node instance at 0xa18302c>, 618: <unpyclib.structure.node instance at 0xa179b8c>, 518: <unpyclib.structure.node instance at 0xa1797cc>, 323: <unpyclib.structure.node instance at 0xa1839ac>, '622&642': <unpyclib.structure.node instance at 0xa1794ec>, 162: <unpyclib.structure.node instance at 0xa1832ec>, 419: <unpyclib.structure.node instance at 0xa16eaac>, 550: <unpyclib.structure.node instance at 0xa17982c>, '106&143': <unpyclib.structure.node instance at 0xa22678c>, 54: <unpyclib.structure.node instance at 0xa18306c>, 321: <unpyclib.structure.node instance at 0xa18392c>, 195: <unpyclib.structure.node instance at 0xa18336c>, 710: <unpyclib.structure.node instance at 0xa1757cc>, 199: <unpyclib.structure.node instance at 0xa1799ac>, 461: <unpyclib.structure.node instance at 0xa17976c>, 335: <unpyclib.structure.node instance at 0xa183a2c>, '63&82': <unpyclib.structure.node instance at 0xa17582c>, 570: <unpyclib.structure.node instance at 0xa17964c>, 361: <unpyclib.structure.node instance at 0xa183aac>, 374: <unpyclib.structure.node instance at 0xa1791cc>, 381: <unpyclib.structure.node instance at 0xa183c2c>}
nname: 6
n 6(None)[__doc__ = ' The scheduler, should not be manipulated directly.\n    For now, one is created and is the default one.'
def __init__(self):
	self.ts = time()
	self._tasks = []
	self.granularity = 0.01
	self._rfds = collections.defaultdict((lambda : []))
	self._idle_infos = dict(threshold=10, on_enter=None, on_exit=None, running=False)
	return None

def add(self, task, ival, gen):
	heappush(self._tasks, (self.ts + ival - self.granularity, task, gen))

def remove(self, task):
	_found = []
	for i, tm in enumerate(self._tasks):
		if t is task:
			_found.append(i)
			continue
	if _found:
		for f in reversed(_found):
			self._tasks.pop(f)
		heapify(self._tasks)

def stop(self):
	self._running = False

def loop(self):
	tasks = self._tasks
	delta = self.granularity
	add = self.add
	self._running = True
	empty_list = []
	idle_since = self.ts

]:
	i: 
	o: 

self.nodes: {6: <unpyclib.structure.node instance at 0xa16a0ac>}
nname: 0
n 0(None)[]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e3cc>}
nname: 0
n 0(None)[stop()
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e60c>}
nname: 0
n 0(None)[i.next()
never_called.start()
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16e48c>}
nname: 0
n 0(None)[import itertools
i = itertools.count()
def nop():
	pass

def killer():
	stop()

def call_count():
	i.next()
	never_called.start()

Task(killer).start(2)
Task(call_count).start(0, loop=True)
never_called = Task(nop).start(1)
loop()
num_iter = i.next()
sched._tasks = []
print num_iter
return num_iter
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa16af8c>}
nname: 0
n 0(None)[log.warn('Use of Timer is DEPRECATED, please use a Task started with loop=True.')
TRACE()
Task.start(self, delay, loop, **kw)
]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa1688ec>}
nname: 6
n 6(None)[__doc__ = ' DEPRECATED: use Task with loop=True '
__slots__ = ['args', 'kw', 'fn', 'stopped', 'timeout', 'delay', 'ival', '_paused', '_generator', '_considered_idle']
def start(self, delay=None, loop=True, **kw):
	log.warn('Use of Timer is DEPRECATED, please use a Task started with loop=True.')
	TRACE()
	Task.start(self, delay, loop, **kw)

]:
	i: 
	o: 

self.nodes: {6: <unpyclib.structure.node instance at 0xa168bec>}
nname: 567
n 567(None)[OneShotTimer = Task
class Timer(Task):
	__doc__ = ' DEPRECATED: use Task with loop=True '
	__slots__ = ['args', 'kw', 'fn', 'stopped', 'timeout', 'delay', 'ival', '_paused', '_generator', '_considered_idle']
	def start(self, delay=None, loop=True, **kw):
		log.warn('Use of Timer is DEPRECATED, please use a Task started with loop=True.')
		TRACE()
		Task.start(self, delay, loop, **kw)



]:
	i: 477(), 566()
	o: 

nname: 566
n 566(None)[]:
	i: 0(f)
	o: 567()

nname: 477
n 477(None)[ref = 722
NB_ITER = 10
avg = sum(<genexpr>(xrange(NB_ITER))) / NB_ITER
print 'Average: %d [~ %d tasks per second|overhead: %.2e] (%d %%, <100%% means slower)' % (avg, avg * 2.8599999999999999, 1.0 / avg * 2.8599999999999999, avg * 100.0 / ref)
]:
	i: 0(t)
	o: 567()

nname: 0
n 0(__name__ == '__main__')[from __future__ import absolute_import, with_statement
__all__ = ['Event', 'CleverEvent', 'Task', 'Timer', 'OneShotTimer', 'events_watch', 'descriptor_watch', 'sched', 'loop', 'stop', 'GlobalTimer', 'global_timer']
import collections
import threading
import select
import errno
import time as _time
from heapq import heapify, heappop, heappush
from peewee.debug import GET_LOGGER, TRACE
from peewee.gettime import time
log = GET_LOGGER(__name__)
class Event(object):
	__doc__ = ' Named events,\n    one can subscribe events and be notified when they are post()ed '
	__slots__ = ['name', 'arg']
	watchers = []
	drop_all = False
	def __init__(self, name):
		self.name = name

	def __str__(self):
		return self.name

	def __hash__(self):
		return self.name

	def __cmp__(self, other):
		return cmp(self.name, other.name)

	def __eq__(self, other):
		return self.name == other.name

	def post(self, arg=None):
		if not Event.drop_all:
			if arg is not None:
				pass
			Task(self._post, arg).start(0, timeout=None)
		return None

	def _post(self, arg=None):
		self.arg = arg
		for watcher in self.watchers:
			watcher(self)



class CleverEvent(object):
	__doc__ = ' Like Event but handle repeat internally '
	__slots__ = ['name', 'arg', '_stop_task', '_loop_task', '_count', 'repeat', 'timeout', 'accels']
	watchers = []
	drop_all = False
	def __init__(self, name, repeat=0.10000000000000001, timeout=0.13, accels=None):
		self.name = name
		self.repeat = repeat
		self._loop_task = Task(self._repeat)
		self._stop_task = Task(self._loop_task.stop)
		self._count = 0

	def __str__(self):
		return self.name

	def __hash__(self):
		return self.name

	def __cmp__(self, other):
		return cmp(self.name, other.name)

	def __eq__(self, other):
		return self.name == other.name

	def post(self, arg=None):
		if not Event.drop_all:
			self._loop_task.args = [arg]
			if not self._loop_task.running:
				self._count = 0
				self._loop_task.start(delay=self.repeat, init_delay=0.01, loop=True)
				self._stop_task.start(self.timeout)
			else:
				self._stop_task.start(self.timeout)

	def _repeat(self, arg):
		self._count += 1
		if 'timeout' in arg and arg['timeout'] is not None:
			pass
		timeout = None
		Task(self._post, arg).start(0, timeout=timeout)
		try:
			self._loop_task.ival = self.accels[self._count]
		except:
			self._loop_task.ival = self.repeat
		return None

	def _post(self, arg=None):
		self.arg = arg
		self.arg['count'] = self._count
		for watcher in self.watchers:
			watcher(self)



def events_drop(bool):
	Event.drop_all = bool
	CleverEvent.drop_all = bool

def events_watch(callback):
	Event.watchers.append(callback)
	CleverEvent.watchers.append(callback)

def descriptor_watch(fd, callback):
	sched._rfds[fd].append(callback)

def set_idle_callback(callback, exit_callback, idle_threshold=10):
	sched._idle_infos['on_enter'] = callback
	sched._idle_infos['on_exit'] = exit_callback
	sched._idle_infos['threshold'] = idle_threshold

class tasked(object):
	__doc__ = "Decorator that makes the target callable run in a Task.\n\n    Useful for e.g. dbus callbacks that are called in a separate thread.\n\n    If you're stacking decorators with side effects, @tasked should be\n    the outermost decorator. Otherwise the code from the outer decorators\n    will be called before the actual function code, and there will *not*\n    be much rejoicing.\n\n    Usage:\n        >>> @tasked(0.1)\n        >>> def foo(*args, **kw):\n        ...     pass\n        >>> # Run foo in a Task with a 0.1s delay\n        >>> foo(bar, baz, fnord=None)\n\n    /!\\ WARNING /!\\ Do *not* use on instance methods that are likely\n    to be called at the same time with different arguments in different threads.\n    Interference between the calls may occur if that happens\n    (e.g. all calls but one being ignored).\n    Yes, that'll be painful to debug, so don't do that, okay?\n    "
	def __init__(self, delay):
		self.task = Task(None)
		self.task.delay = delay
		return None

	def __call__(self, fn):
		self.task.fn = fn
		def decorated(*args, **args):
			log.debug('Starting Task for %s', self.task.fn)
			self.task.args, self.task.kw = args, kw
			self.task.start()

		decorated.task = self.task
		return decorated



class Task(object):
	__doc__ = "A schedulable task.\nInteresting properties:\n    running (bool): is the task running ?\n    delay: base delay (interval in loop mode)\n\nExemples:\n    # Will start task after 5s and then every second\n    task.start(1, loop=True, init_delay=5)\n\n    # Start a task & stop it before anything\n    t = Task(sys.stdout.write, 'Hello world\\n').start(5)\n    t.stop()\n\nImplementation Notes:\n    Two tasks started within the same task and with the same delay will\n    be scheduled for the *same* time be cause the reference time is the\n    begin of the current task.\n    The probability for another task to be executed between those two tasks is very very low.\n    "
	__slots__ = ['args', 'kw', 'fn', 'running', 'timeout', 'delay', 'ival', '_paused', '_generator', '_considered_idle']
	def __init__(self, fn, *args, **args):
		self.args = args
		self.kw = kw
		self.fn = fn
		self.ival = None
		self.running = False
		self.timeout = None
		self._generator = None
		self._considered_idle = False
		return None

	def __repr__(self):
		if self.running:
			pass
		if self._considered_idle:
			pass
		if self.ival is None:
			pass
		return '<%s %s task %s calling %s>' % ('stopped', 'busy', 'every %ss' % self.ival, self.fn)

	def start(self, delay=None, loop=None, timeout=None, init_delay=None, consider_idle=None):
		if self.running:
			self.stop()
		self.running = sched.ts
		self._paused = None
		if consider_idle is not None:
			self._considered_idle = consider_idle
		if delay is None:
			delay = self.delay
		if loop is None:
			if self.ival is None:
				pass
			loop = True
		if delay is not None:
			if delay is not None:
				pass
			self.delay = 1.0
		if timeout is not None:
			self.timeout = timeout
		if loop:
			pass
		self.ival = None
		self._generator = self._generate()
		if init_delay is not None:
			pass
		sched.add(self, delay, self._generator)
		return self

	def pause(self):
		if self._paused is None:
			self._paused = sched.ts - self.running
			self.stop()
			return self._paused
		return None

	def unpause(self):
		if self._paused is not None:
			self.running = sched.ts
			self._generator = self._generate()
			remaining = self.delay - self._paused
			sched.add(self, remaining, self._generator)
			self._paused = None
			return remaining
		return None

	def stop(self):
		self.running = False
		if self._generator is not None:
			try:
				self._generator.close()
			except ValueError:
				log.warning('%s has running timer!', self)
			self._generator = None
			sched.remove(self)
		return None

	def _generate(self):
		while True:
			ret = None
			try:
				ret = self.fn(*self.args, **self.kw)
			except StopIteration:
				break
			except:
				except Exception, e:
					log.error('Task failed: %s: %s' % (self, e))
					TRACE()
			finally:
				if not self.running:
					yield None
			if ret.__class__ is float:
				yield ret
				continue
			yield self.ival
		return None



class HookThread(.):
	__doc__ = '\n    This class provide a Thread skeleton, typically in order\n    to be started by a ThreadedTask object.\n    The main method, which is executed in run() is func_process(), that MUST\n    be overriden.\n    Control methods are available, and are called when func_process succeded, or failed,\n    or is canceled, and to retrieve some infos\n    !!! In order to be canceled, func_process has to be asynchronous\n    '
	def __init__(self):
		threading.Thread.__init__(self)
		self.completed = threading.Event()
		self.started = threading.Event()

	def run(self):
		try:
			self.func_process()
			self.completed.wait()
			log.debug('completed set !')
		except Exception:
			self.on_failure()
		else:
			self.on_success()

	def func_process(self, *args, **args):
		raise NotImplementedError

	def get_infos(self):
		pass

	def on_cancel(self):
		log.debug(self)
		self.completed.set()

	def on_success(self):
		log.debug(self)
		try:
			self.controler.stop()
		except AttributeError:
			pass

	def on_failure(self):
		log.debug(self)
		try:
			self.controler.stop()
		except AttributeError:
			pass



class ThreadedTask(Task):
	__doc__ = '\n    This class provides a Task that mainly do 2 things :\n        - start the HookThread object passed in parameters and control it\n        - retrieves infos on this HookThread and report them via progress method()\n    '
	def __init__(self, job, *args, **args):
		Task.__init__(self, fn=None)
		self.job = job
		self.job.controler = self
		self.fn = self._get_job_infos
		return None

	def __repr__(self):
		if self.running:
			pass
		if self._considered_idle:
			pass
		if self.ival is None:
			pass
		return '<%s %s task %s getting infos from %s>' % ('stopped', 'busy', 'every %ss' % self.ival, self.__class__.__name__)

	def start(self, delay=None, loop=True, timeout=None, init_delay=None, consider_idle=None):
		self.job.start()
		Task.start(self, delay, loop, timeout, init_delay, consider_idle)

	def report_job_progress(self, infos_dict):
		pass

	def _get_job_infos(self):
		self.report_job_progress(self.job.get_infos())

	def on_terminate(self):
		pass

	def cancel(self):
		job = self.job
		try:
			job.on_cancel()
			log.debug('Thread %r canceled', job)
		except Exception, e:
			log.error('Unable to cancel Thread %r <==%s==>', job, e)
		finally:
			self.stop()

	def stop(self):
		self.on_terminate()
		Task.stop(self)



class GlobalTimer(object):
	__doc__ = '\n    GlobalTimer is in charge to handle global tasks in notifier.\n    Tasks can be added and are accesible by a simple name.\n    Callbacks can be registered, and so executed each time the task ticks.\n    '
	def __init__(self):
		self._indexed_tasks = {}
		self._global_tasks = collections.defaultdict(dict)
		self.add('clock', self.global_clock, delay=1, loop=True, consider_idle=True)

	def callbacks_by_task(self, task_name):
		return self._global_tasks[self._indexed_tasks[task_name]]

	def register_callback(self, task_name, obs, *args, **args):
		self.callbacks_by_task(task_name)[obs] = (args, kw)

	def unregister_callback(self, task_name, obs):
		self.callbacks_by_task(task_name).pop(obs)

	def add(self, task_name, fn=None, args=None, kwargs=None, delay=0, loop=None, timeout=None, init_delay=None, consider_idle=None):
		if fn is not None:
			if args is not None:
				pass
			args = tuple()
			if kwargs is not None:
				pass
			kwargs = {}
			def _fn():
				log.debug('GlobalTimer: %s' % task_name)
				ret = fn(*args, **kwargs)
				self._dispatch(task_name, ret)

			t = Task(_fn)
		else:
			t = Task(self._dispatch, task_name)
		self._indexed_tasks[task_name] = t
		self._global_tasks[t] = {}
		t.start(delay, loop, timeout, init_delay, consider_idle)
		return None

	def remove(self, task_name):
		t = self._indexed_tasks.pop(task_name)
		t.stop()
		self._global_tasks.pop(t)

	def stop(self):
		for task in self._indexed_tasks.itervalues():
			task.stop()
		self._indexed_tasks.clear()
		self._global_tasks.clear()

	def _dispatch(self, task_name, ret=None):
		log.debug('GlobalTimer: %s' % task_name)
		for obs, args in self.callbacks_by_task(task_name).iteritems():
			if ret is not None:
				obs(ret, *args, **kw)
				continue
			obs(*args, **kw)
		return None

	def global_clock(self):
		return _time.time()



class Scheduler(object):
	__doc__ = ' The scheduler, should not be manipulated directly.\n    For now, one is created and is the default one.'
	def __init__(self):
		self.ts = time()
		self._tasks = []
		self.granularity = 0.01
		self._rfds = collections.defaultdict((lambda : []))
		self._idle_infos = dict(threshold=10, on_enter=None, on_exit=None, running=False)
		return None

	def add(self, task, ival, gen):
		heappush(self._tasks, (self.ts + ival - self.granularity, task, gen))

	def remove(self, task):
		_found = []
		for i, tm in enumerate(self._tasks):
			if t is task:
				_found.append(i)
				continue
		if _found:
			for f in reversed(_found):
				self._tasks.pop(f)
			heapify(self._tasks)

	def stop(self):
		self._running = False

	def loop(self):
		tasks = self._tasks
		delta = self.granularity
		add = self.add
		self._running = True
		empty_list = []
		idle_since = self.ts



sched = Scheduler()
loop = sched.loop
stop = sched.stop
global_timer = GlobalTimer()
def main():
	import itertools
	i = itertools.count()
	def nop():
		pass

	def killer():
		stop()

	def call_count():
		i.next()
		never_called.start()

	Task(killer).start(2)
	Task(call_count).start(0, loop=True)
	never_called = Task(nop).start(1)
	loop()
	num_iter = i.next()
	sched._tasks = []
	print num_iter
	return num_iter

]:
	i: 
	o: 477(t), 566(f)

nname: 0
n 0(None)[from __future__ import absolute_import, with_statement
__all__ = ['Event', 'CleverEvent', 'Task', 'Timer', 'OneShotTimer', 'events_watch', 'descriptor_watch', 'sched', 'loop', 'stop', 'GlobalTimer', 'global_timer']
import collections
import threading
import select
import errno
import time as _time
from heapq import heapify, heappop, heappush
from peewee.debug import GET_LOGGER, TRACE
from peewee.gettime import time
log = GET_LOGGER(__name__)
class Event(object):
	__doc__ = ' Named events,\n    one can subscribe events and be notified when they are post()ed '
	__slots__ = ['name', 'arg']
	watchers = []
	drop_all = False
	def __init__(self, name):
		self.name = name

	def __str__(self):
		return self.name

	def __hash__(self):
		return self.name

	def __cmp__(self, other):
		return cmp(self.name, other.name)

	def __eq__(self, other):
		return self.name == other.name

	def post(self, arg=None):
		if not Event.drop_all:
			if arg is not None:
				pass
			Task(self._post, arg).start(0, timeout=None)
		return None

	def _post(self, arg=None):
		self.arg = arg
		for watcher in self.watchers:
			watcher(self)



class CleverEvent(object):
	__doc__ = ' Like Event but handle repeat internally '
	__slots__ = ['name', 'arg', '_stop_task', '_loop_task', '_count', 'repeat', 'timeout', 'accels']
	watchers = []
	drop_all = False
	def __init__(self, name, repeat=0.10000000000000001, timeout=0.13, accels=None):
		self.name = name
		self.repeat = repeat
		self._loop_task = Task(self._repeat)
		self._stop_task = Task(self._loop_task.stop)
		self._count = 0

	def __str__(self):
		return self.name

	def __hash__(self):
		return self.name

	def __cmp__(self, other):
		return cmp(self.name, other.name)

	def __eq__(self, other):
		return self.name == other.name

	def post(self, arg=None):
		if not Event.drop_all:
			self._loop_task.args = [arg]
			if not self._loop_task.running:
				self._count = 0
				self._loop_task.start(delay=self.repeat, init_delay=0.01, loop=True)
				self._stop_task.start(self.timeout)
			else:
				self._stop_task.start(self.timeout)

	def _repeat(self, arg):
		self._count += 1
		if 'timeout' in arg and arg['timeout'] is not None:
			pass
		timeout = None
		Task(self._post, arg).start(0, timeout=timeout)
		try:
			self._loop_task.ival = self.accels[self._count]
		except:
			self._loop_task.ival = self.repeat
		return None

	def _post(self, arg=None):
		self.arg = arg
		self.arg['count'] = self._count
		for watcher in self.watchers:
			watcher(self)



def events_drop(bool):
	Event.drop_all = bool
	CleverEvent.drop_all = bool

def events_watch(callback):
	Event.watchers.append(callback)
	CleverEvent.watchers.append(callback)

def descriptor_watch(fd, callback):
	sched._rfds[fd].append(callback)

def set_idle_callback(callback, exit_callback, idle_threshold=10):
	sched._idle_infos['on_enter'] = callback
	sched._idle_infos['on_exit'] = exit_callback
	sched._idle_infos['threshold'] = idle_threshold

class tasked(object):
	__doc__ = "Decorator that makes the target callable run in a Task.\n\n    Useful for e.g. dbus callbacks that are called in a separate thread.\n\n    If you're stacking decorators with side effects, @tasked should be\n    the outermost decorator. Otherwise the code from the outer decorators\n    will be called before the actual function code, and there will *not*\n    be much rejoicing.\n\n    Usage:\n        >>> @tasked(0.1)\n        >>> def foo(*args, **kw):\n        ...     pass\n        >>> # Run foo in a Task with a 0.1s delay\n        >>> foo(bar, baz, fnord=None)\n\n    /!\\ WARNING /!\\ Do *not* use on instance methods that are likely\n    to be called at the same time with different arguments in different threads.\n    Interference between the calls may occur if that happens\n    (e.g. all calls but one being ignored).\n    Yes, that'll be painful to debug, so don't do that, okay?\n    "
	def __init__(self, delay):
		self.task = Task(None)
		self.task.delay = delay
		return None

	def __call__(self, fn):
		self.task.fn = fn
		def decorated(*args, **args):
			log.debug('Starting Task for %s', self.task.fn)
			self.task.args, self.task.kw = args, kw
			self.task.start()

		decorated.task = self.task
		return decorated



class Task(object):
	__doc__ = "A schedulable task.\nInteresting properties:\n    running (bool): is the task running ?\n    delay: base delay (interval in loop mode)\n\nExemples:\n    # Will start task after 5s and then every second\n    task.start(1, loop=True, init_delay=5)\n\n    # Start a task & stop it before anything\n    t = Task(sys.stdout.write, 'Hello world\\n').start(5)\n    t.stop()\n\nImplementation Notes:\n    Two tasks started within the same task and with the same delay will\n    be scheduled for the *same* time be cause the reference time is the\n    begin of the current task.\n    The probability for another task to be executed between those two tasks is very very low.\n    "
	__slots__ = ['args', 'kw', 'fn', 'running', 'timeout', 'delay', 'ival', '_paused', '_generator', '_considered_idle']
	def __init__(self, fn, *args, **args):
		self.args = args
		self.kw = kw
		self.fn = fn
		self.ival = None
		self.running = False
		self.timeout = None
		self._generator = None
		self._considered_idle = False
		return None

	def __repr__(self):
		if self.running:
			pass
		if self._considered_idle:
			pass
		if self.ival is None:
			pass
		return '<%s %s task %s calling %s>' % ('stopped', 'busy', 'every %ss' % self.ival, self.fn)

	def start(self, delay=None, loop=None, timeout=None, init_delay=None, consider_idle=None):
		if self.running:
			self.stop()
		self.running = sched.ts
		self._paused = None
		if consider_idle is not None:
			self._considered_idle = consider_idle
		if delay is None:
			delay = self.delay
		if loop is None:
			if self.ival is None:
				pass
			loop = True
		if delay is not None:
			if delay is not None:
				pass
			self.delay = 1.0
		if timeout is not None:
			self.timeout = timeout
		if loop:
			pass
		self.ival = None
		self._generator = self._generate()
		if init_delay is not None:
			pass
		sched.add(self, delay, self._generator)
		return self

	def pause(self):
		if self._paused is None:
			self._paused = sched.ts - self.running
			self.stop()
			return self._paused
		return None

	def unpause(self):
		if self._paused is not None:
			self.running = sched.ts
			self._generator = self._generate()
			remaining = self.delay - self._paused
			sched.add(self, remaining, self._generator)
			self._paused = None
			return remaining
		return None

	def stop(self):
		self.running = False
		if self._generator is not None:
			try:
				self._generator.close()
			except ValueError:
				log.warning('%s has running timer!', self)
			self._generator = None
			sched.remove(self)
		return None

	def _generate(self):
		while True:
			ret = None
			try:
				ret = self.fn(*self.args, **self.kw)
			except StopIteration:
				break
			except:
				except Exception, e:
					log.error('Task failed: %s: %s' % (self, e))
					TRACE()
			finally:
				if not self.running:
					yield None
			if ret.__class__ is float:
				yield ret
				continue
			yield self.ival
		return None



class HookThread(.):
	__doc__ = '\n    This class provide a Thread skeleton, typically in order\n    to be started by a ThreadedTask object.\n    The main method, which is executed in run() is func_process(), that MUST\n    be overriden.\n    Control methods are available, and are called when func_process succeded, or failed,\n    or is canceled, and to retrieve some infos\n    !!! In order to be canceled, func_process has to be asynchronous\n    '
	def __init__(self):
		threading.Thread.__init__(self)
		self.completed = threading.Event()
		self.started = threading.Event()

	def run(self):
		try:
			self.func_process()
			self.completed.wait()
			log.debug('completed set !')
		except Exception:
			self.on_failure()
		else:
			self.on_success()

	def func_process(self, *args, **args):
		raise NotImplementedError

	def get_infos(self):
		pass

	def on_cancel(self):
		log.debug(self)
		self.completed.set()

	def on_success(self):
		log.debug(self)
		try:
			self.controler.stop()
		except AttributeError:
			pass

	def on_failure(self):
		log.debug(self)
		try:
			self.controler.stop()
		except AttributeError:
			pass



class ThreadedTask(Task):
	__doc__ = '\n    This class provides a Task that mainly do 2 things :\n        - start the HookThread object passed in parameters and control it\n        - retrieves infos on this HookThread and report them via progress method()\n    '
	def __init__(self, job, *args, **args):
		Task.__init__(self, fn=None)
		self.job = job
		self.job.controler = self
		self.fn = self._get_job_infos
		return None

	def __repr__(self):
		if self.running:
			pass
		if self._considered_idle:
			pass
		if self.ival is None:
			pass
		return '<%s %s task %s getting infos from %s>' % ('stopped', 'busy', 'every %ss' % self.ival, self.__class__.__name__)

	def start(self, delay=None, loop=True, timeout=None, init_delay=None, consider_idle=None):
		self.job.start()
		Task.start(self, delay, loop, timeout, init_delay, consider_idle)

	def report_job_progress(self, infos_dict):
		pass

	def _get_job_infos(self):
		self.report_job_progress(self.job.get_infos())

	def on_terminate(self):
		pass

	def cancel(self):
		job = self.job
		try:
			job.on_cancel()
			log.debug('Thread %r canceled', job)
		except Exception, e:
			log.error('Unable to cancel Thread %r <==%s==>', job, e)
		finally:
			self.stop()

	def stop(self):
		self.on_terminate()
		Task.stop(self)



class GlobalTimer(object):
	__doc__ = '\n    GlobalTimer is in charge to handle global tasks in notifier.\n    Tasks can be added and are accesible by a simple name.\n    Callbacks can be registered, and so executed each time the task ticks.\n    '
	def __init__(self):
		self._indexed_tasks = {}
		self._global_tasks = collections.defaultdict(dict)
		self.add('clock', self.global_clock, delay=1, loop=True, consider_idle=True)

	def callbacks_by_task(self, task_name):
		return self._global_tasks[self._indexed_tasks[task_name]]

	def register_callback(self, task_name, obs, *args, **args):
		self.callbacks_by_task(task_name)[obs] = (args, kw)

	def unregister_callback(self, task_name, obs):
		self.callbacks_by_task(task_name).pop(obs)

	def add(self, task_name, fn=None, args=None, kwargs=None, delay=0, loop=None, timeout=None, init_delay=None, consider_idle=None):
		if fn is not None:
			if args is not None:
				pass
			args = tuple()
			if kwargs is not None:
				pass
			kwargs = {}
			def _fn():
				log.debug('GlobalTimer: %s' % task_name)
				ret = fn(*args, **kwargs)
				self._dispatch(task_name, ret)

			t = Task(_fn)
		else:
			t = Task(self._dispatch, task_name)
		self._indexed_tasks[task_name] = t
		self._global_tasks[t] = {}
		t.start(delay, loop, timeout, init_delay, consider_idle)
		return None

	def remove(self, task_name):
		t = self._indexed_tasks.pop(task_name)
		t.stop()
		self._global_tasks.pop(t)

	def stop(self):
		for task in self._indexed_tasks.itervalues():
			task.stop()
		self._indexed_tasks.clear()
		self._global_tasks.clear()

	def _dispatch(self, task_name, ret=None):
		log.debug('GlobalTimer: %s' % task_name)
		for obs, args in self.callbacks_by_task(task_name).iteritems():
			if ret is not None:
				obs(ret, *args, **kw)
				continue
			obs(*args, **kw)
		return None

	def global_clock(self):
		return _time.time()



class Scheduler(object):
	__doc__ = ' The scheduler, should not be manipulated directly.\n    For now, one is created and is the default one.'
	def __init__(self):
		self.ts = time()
		self._tasks = []
		self.granularity = 0.01
		self._rfds = collections.defaultdict((lambda : []))
		self._idle_infos = dict(threshold=10, on_enter=None, on_exit=None, running=False)
		return None

	def add(self, task, ival, gen):
		heappush(self._tasks, (self.ts + ival - self.granularity, task, gen))

	def remove(self, task):
		_found = []
		for i, tm in enumerate(self._tasks):
			if t is task:
				_found.append(i)
				continue
		if _found:
			for f in reversed(_found):
				self._tasks.pop(f)
			heapify(self._tasks)

	def stop(self):
		self._running = False

	def loop(self):
		tasks = self._tasks
		delta = self.granularity
		add = self.add
		self._running = True
		empty_list = []
		idle_since = self.ts



sched = Scheduler()
loop = sched.loop
stop = sched.stop
global_timer = GlobalTimer()
def main():
	import itertools
	i = itertools.count()
	def nop():
		pass

	def killer():
		stop()

	def call_count():
		i.next()
		never_called.start()

	Task(killer).start(2)
	Task(call_count).start(0, loop=True)
	never_called = Task(nop).start(1)
	loop()
	num_iter = i.next()
	sched._tasks = []
	print num_iter
	return num_iter

if __name__ == '__main__':
	ref = 722
	NB_ITER = 10
	avg = sum(<genexpr>(xrange(NB_ITER))) / NB_ITER
	print 'Average: %d [~ %d tasks per second|overhead: %.2e] (%d %%, <100%% means slower)' % (avg, avg * 2.8599999999999999, 1.0 / avg * 2.8599999999999999, avg * 100.0 / ref)
OneShotTimer = Task
class Timer(Task):
	__doc__ = ' DEPRECATED: use Task with loop=True '
	__slots__ = ['args', 'kw', 'fn', 'stopped', 'timeout', 'delay', 'ival', '_paused', '_generator', '_considered_idle']
	def start(self, delay=None, loop=True, **kw):
		log.warn('Use of Timer is DEPRECATED, please use a Task started with loop=True.')
		TRACE()
		Task.start(self, delay, loop, **kw)



]:
	i: 
	o: 

self.nodes: {0: <unpyclib.structure.node instance at 0xa1567ec>}
from __future__ import absolute_import, with_statement
__all__ = ['Event', 'CleverEvent', 'Task', 'Timer', 'OneShotTimer', 'events_watch', 'descriptor_watch', 'sched', 'loop', 'stop', 'GlobalTimer', 'global_timer']
import collections
import threading
import select
import errno
import time as _time
from heapq import heapify, heappop, heappush
from peewee.debug import GET_LOGGER, TRACE
from peewee.gettime import time
log = GET_LOGGER(__name__)
class Event(object):
	__doc__ = ' Named events,\n    one can subscribe events and be notified when they are post()ed '
	__slots__ = ['name', 'arg']
	watchers = []
	drop_all = False
	def __init__(self, name):
		self.name = name

	def __str__(self):
		return self.name

	def __hash__(self):
		return self.name

	def __cmp__(self, other):
		return cmp(self.name, other.name)

	def __eq__(self, other):
		return self.name == other.name

	def post(self, arg=None):
		if not Event.drop_all:
			if arg is not None:
				pass
			Task(self._post, arg).start(0, timeout=None)
		return None

	def _post(self, arg=None):
		self.arg = arg
		for watcher in self.watchers:
			watcher(self)



class CleverEvent(object):
	__doc__ = ' Like Event but handle repeat internally '
	__slots__ = ['name', 'arg', '_stop_task', '_loop_task', '_count', 'repeat', 'timeout', 'accels']
	watchers = []
	drop_all = False
	def __init__(self, name, repeat=0.10000000000000001, timeout=0.13, accels=None):
		self.name = name
		self.repeat = repeat
		self._loop_task = Task(self._repeat)
		self._stop_task = Task(self._loop_task.stop)
		self._count = 0

	def __str__(self):
		return self.name

	def __hash__(self):
		return self.name

	def __cmp__(self, other):
		return cmp(self.name, other.name)

	def __eq__(self, other):
		return self.name == other.name

	def post(self, arg=None):
		if not Event.drop_all:
			self._loop_task.args = [arg]
			if not self._loop_task.running:
				self._count = 0
				self._loop_task.start(delay=self.repeat, init_delay=0.01, loop=True)
				self._stop_task.start(self.timeout)
			else:
				self._stop_task.start(self.timeout)

	def _repeat(self, arg):
		self._count += 1
		if 'timeout' in arg and arg['timeout'] is not None:
			pass
		timeout = None
		Task(self._post, arg).start(0, timeout=timeout)
		try:
			self._loop_task.ival = self.accels[self._count]
		except:
			self._loop_task.ival = self.repeat
		return None

	def _post(self, arg=None):
		self.arg = arg
		self.arg['count'] = self._count
		for watcher in self.watchers:
			watcher(self)



def events_drop(bool):
	Event.drop_all = bool
	CleverEvent.drop_all = bool

def events_watch(callback):
	Event.watchers.append(callback)
	CleverEvent.watchers.append(callback)

def descriptor_watch(fd, callback):
	sched._rfds[fd].append(callback)

def set_idle_callback(callback, exit_callback, idle_threshold=10):
	sched._idle_infos['on_enter'] = callback
	sched._idle_infos['on_exit'] = exit_callback
	sched._idle_infos['threshold'] = idle_threshold

class tasked(object):
	__doc__ = "Decorator that makes the target callable run in a Task.\n\n    Useful for e.g. dbus callbacks that are called in a separate thread.\n\n    If you're stacking decorators with side effects, @tasked should be\n    the outermost decorator. Otherwise the code from the outer decorators\n    will be called before the actual function code, and there will *not*\n    be much rejoicing.\n\n    Usage:\n        >>> @tasked(0.1)\n        >>> def foo(*args, **kw):\n        ...     pass\n        >>> # Run foo in a Task with a 0.1s delay\n        >>> foo(bar, baz, fnord=None)\n\n    /!\\ WARNING /!\\ Do *not* use on instance methods that are likely\n    to be called at the same time with different arguments in different threads.\n    Interference between the calls may occur if that happens\n    (e.g. all calls but one being ignored).\n    Yes, that'll be painful to debug, so don't do that, okay?\n    "
	def __init__(self, delay):
		self.task = Task(None)
		self.task.delay = delay
		return None

	def __call__(self, fn):
		self.task.fn = fn
		def decorated(*args, **args):
			log.debug('Starting Task for %s', self.task.fn)
			self.task.args, self.task.kw = args, kw
			self.task.start()

		decorated.task = self.task
		return decorated



class Task(object):
	__doc__ = "A schedulable task.\nInteresting properties:\n    running (bool): is the task running ?\n    delay: base delay (interval in loop mode)\n\nExemples:\n    # Will start task after 5s and then every second\n    task.start(1, loop=True, init_delay=5)\n\n    # Start a task & stop it before anything\n    t = Task(sys.stdout.write, 'Hello world\\n').start(5)\n    t.stop()\n\nImplementation Notes:\n    Two tasks started within the same task and with the same delay will\n    be scheduled for the *same* time be cause the reference time is the\n    begin of the current task.\n    The probability for another task to be executed between those two tasks is very very low.\n    "
	__slots__ = ['args', 'kw', 'fn', 'running', 'timeout', 'delay', 'ival', '_paused', '_generator', '_considered_idle']
	def __init__(self, fn, *args, **args):
		self.args = args
		self.kw = kw
		self.fn = fn
		self.ival = None
		self.running = False
		self.timeout = None
		self._generator = None
		self._considered_idle = False
		return None

	def __repr__(self):
		if self.running:
			pass
		if self._considered_idle:
			pass
		if self.ival is None:
			pass
		return '<%s %s task %s calling %s>' % ('stopped', 'busy', 'every %ss' % self.ival, self.fn)

	def start(self, delay=None, loop=None, timeout=None, init_delay=None, consider_idle=None):
		if self.running:
			self.stop()
		self.running = sched.ts
		self._paused = None
		if consider_idle is not None:
			self._considered_idle = consider_idle
		if delay is None:
			delay = self.delay
		if loop is None:
			if self.ival is None:
				pass
			loop = True
		if delay is not None:
			if delay is not None:
				pass
			self.delay = 1.0
		if timeout is not None:
			self.timeout = timeout
		if loop:
			pass
		self.ival = None
		self._generator = self._generate()
		if init_delay is not None:
			pass
		sched.add(self, delay, self._generator)
		return self

	def pause(self):
		if self._paused is None:
			self._paused = sched.ts - self.running
			self.stop()
			return self._paused
		return None

	def unpause(self):
		if self._paused is not None:
			self.running = sched.ts
			self._generator = self._generate()
			remaining = self.delay - self._paused
			sched.add(self, remaining, self._generator)
			self._paused = None
			return remaining
		return None

	def stop(self):
		self.running = False
		if self._generator is not None:
			try:
				self._generator.close()
			except ValueError:
				log.warning('%s has running timer!', self)
			self._generator = None
			sched.remove(self)
		return None

	def _generate(self):
		while True:
			ret = None
			try:
				ret = self.fn(*self.args, **self.kw)
			except StopIteration:
				break
			except:
				except Exception, e:
					log.error('Task failed: %s: %s' % (self, e))
					TRACE()
			finally:
				if not self.running:
					yield None
			if ret.__class__ is float:
				yield ret
				continue
			yield self.ival
		return None



class HookThread(.):
	__doc__ = '\n    This class provide a Thread skeleton, typically in order\n    to be started by a ThreadedTask object.\n    The main method, which is executed in run() is func_process(), that MUST\n    be overriden.\n    Control methods are available, and are called when func_process succeded, or failed,\n    or is canceled, and to retrieve some infos\n    !!! In order to be canceled, func_process has to be asynchronous\n    '
	def __init__(self):
		threading.Thread.__init__(self)
		self.completed = threading.Event()
		self.started = threading.Event()

	def run(self):
		try:
			self.func_process()
			self.completed.wait()
			log.debug('completed set !')
		except Exception:
			self.on_failure()
		else:
			self.on_success()

	def func_process(self, *args, **args):
		raise NotImplementedError

	def get_infos(self):
		pass

	def on_cancel(self):
		log.debug(self)
		self.completed.set()

	def on_success(self):
		log.debug(self)
		try:
			self.controler.stop()
		except AttributeError:
			pass

	def on_failure(self):
		log.debug(self)
		try:
			self.controler.stop()
		except AttributeError:
			pass



class ThreadedTask(Task):
	__doc__ = '\n    This class provides a Task that mainly do 2 things :\n        - start the HookThread object passed in parameters and control it\n        - retrieves infos on this HookThread and report them via progress method()\n    '
	def __init__(self, job, *args, **args):
		Task.__init__(self, fn=None)
		self.job = job
		self.job.controler = self
		self.fn = self._get_job_infos
		return None

	def __repr__(self):
		if self.running:
			pass
		if self._considered_idle:
			pass
		if self.ival is None:
			pass
		return '<%s %s task %s getting infos from %s>' % ('stopped', 'busy', 'every %ss' % self.ival, self.__class__.__name__)

	def start(self, delay=None, loop=True, timeout=None, init_delay=None, consider_idle=None):
		self.job.start()
		Task.start(self, delay, loop, timeout, init_delay, consider_idle)

	def report_job_progress(self, infos_dict):
		pass

	def _get_job_infos(self):
		self.report_job_progress(self.job.get_infos())

	def on_terminate(self):
		pass

	def cancel(self):
		job = self.job
		try:
			job.on_cancel()
			log.debug('Thread %r canceled', job)
		except Exception, e:
			log.error('Unable to cancel Thread %r <==%s==>', job, e)
		finally:
			self.stop()

	def stop(self):
		self.on_terminate()
		Task.stop(self)



class GlobalTimer(object):
	__doc__ = '\n    GlobalTimer is in charge to handle global tasks in notifier.\n    Tasks can be added and are accesible by a simple name.\n    Callbacks can be registered, and so executed each time the task ticks.\n    '
	def __init__(self):
		self._indexed_tasks = {}
		self._global_tasks = collections.defaultdict(dict)
		self.add('clock', self.global_clock, delay=1, loop=True, consider_idle=True)

	def callbacks_by_task(self, task_name):
		return self._global_tasks[self._indexed_tasks[task_name]]

	def register_callback(self, task_name, obs, *args, **args):
		self.callbacks_by_task(task_name)[obs] = (args, kw)

	def unregister_callback(self, task_name, obs):
		self.callbacks_by_task(task_name).pop(obs)

	def add(self, task_name, fn=None, args=None, kwargs=None, delay=0, loop=None, timeout=None, init_delay=None, consider_idle=None):
		if fn is not None:
			if args is not None:
				pass
			args = tuple()
			if kwargs is not None:
				pass
			kwargs = {}
			def _fn():
				log.debug('GlobalTimer: %s' % task_name)
				ret = fn(*args, **kwargs)
				self._dispatch(task_name, ret)

			t = Task(_fn)
		else:
			t = Task(self._dispatch, task_name)
		self._indexed_tasks[task_name] = t
		self._global_tasks[t] = {}
		t.start(delay, loop, timeout, init_delay, consider_idle)
		return None

	def remove(self, task_name):
		t = self._indexed_tasks.pop(task_name)
		t.stop()
		self._global_tasks.pop(t)

	def stop(self):
		for task in self._indexed_tasks.itervalues():
			task.stop()
		self._indexed_tasks.clear()
		self._global_tasks.clear()

	def _dispatch(self, task_name, ret=None):
		log.debug('GlobalTimer: %s' % task_name)
		for obs, args in self.callbacks_by_task(task_name).iteritems():
			if ret is not None:
				obs(ret, *args, **kw)
				continue
			obs(*args, **kw)
		return None

	def global_clock(self):
		return _time.time()



class Scheduler(object):
	__doc__ = ' The scheduler, should not be manipulated directly.\n    For now, one is created and is the default one.'
	def __init__(self):
		self.ts = time()
		self._tasks = []
		self.granularity = 0.01
		self._rfds = collections.defaultdict((lambda : []))
		self._idle_infos = dict(threshold=10, on_enter=None, on_exit=None, running=False)
		return None

	def add(self, task, ival, gen):
		heappush(self._tasks, (self.ts + ival - self.granularity, task, gen))

	def remove(self, task):
		_found = []
		for i, tm in enumerate(self._tasks):
			if t is task:
				_found.append(i)
				continue
		if _found:
			for f in reversed(_found):
				self._tasks.pop(f)
			heapify(self._tasks)

	def stop(self):
		self._running = False

	def loop(self):
		tasks = self._tasks
		delta = self.granularity
		add = self.add
		self._running = True
		empty_list = []
		idle_since = self.ts



sched = Scheduler()
loop = sched.loop
stop = sched.stop
global_timer = GlobalTimer()
def main():
	import itertools
	i = itertools.count()
	def nop():
		pass

	def killer():
		stop()

	def call_count():
		i.next()
		never_called.start()

	Task(killer).start(2)
	Task(call_count).start(0, loop=True)
	never_called = Task(nop).start(1)
	loop()
	num_iter = i.next()
	sched._tasks = []
	print num_iter
	return num_iter

if __name__ == '__main__':
	ref = 722
	NB_ITER = 10
	avg = sum(<genexpr>(xrange(NB_ITER))) / NB_ITER
	print 'Average: %d [~ %d tasks per second|overhead: %.2e] (%d %%, <100%% means slower)' % (avg, avg * 2.8599999999999999, 1.0 / avg * 2.8599999999999999, avg * 100.0 / ref)
OneShotTimer = Task
class Timer(Task):
	__doc__ = ' DEPRECATED: use Task with loop=True '
	__slots__ = ['args', 'kw', 'fn', 'stopped', 'timeout', 'delay', 'ival', '_paused', '_generator', '_considered_idle']
	def start(self, delay=None, loop=True, **kw):
		log.warn('Use of Timer is DEPRECATED, please use a Task started with loop=True.')
		TRACE()
		Task.start(self, delay, loop, **kw)



